1*912701f9SAndroid Build Coastguard Worker## Unicode Technical Standard #35 2*912701f9SAndroid Build Coastguard Worker 3*912701f9SAndroid Build Coastguard Worker# Unicode Locale Data Markup Language (LDML)<br/>Part 9: Message Format 4*912701f9SAndroid Build Coastguard Worker 5*912701f9SAndroid Build Coastguard Worker|Version|45 | 6*912701f9SAndroid Build Coastguard Worker|-------|------------------------| 7*912701f9SAndroid Build Coastguard Worker|Editors|Addison Phillips and [other CLDR committee members](tr35.md#Acknowledgments)| 8*912701f9SAndroid Build Coastguard Worker 9*912701f9SAndroid Build Coastguard WorkerFor the full header, summary, and status, see [Part 1: Core](tr35.md). 10*912701f9SAndroid Build Coastguard Worker 11*912701f9SAndroid Build Coastguard Worker### _Summary_ 12*912701f9SAndroid Build Coastguard Worker 13*912701f9SAndroid Build Coastguard WorkerThis specification defines the data model, syntax, processing, and conformance requirements for the next generation of dynamic messages. 14*912701f9SAndroid Build Coastguard Worker 15*912701f9SAndroid Build Coastguard WorkerThis is a partial document, describing only those parts of the LDML that are relevant for message format. For the other parts of the LDML see the [main LDML document](tr35.md) and the links above. 16*912701f9SAndroid Build Coastguard Worker 17*912701f9SAndroid Build Coastguard Worker### _Status_ 18*912701f9SAndroid Build Coastguard Worker 19*912701f9SAndroid Build Coastguard Worker<!-- _This is a draft document which may be updated, replaced, or superseded by other documents at any time. 20*912701f9SAndroid Build Coastguard WorkerPublication does not imply endorsement by the Unicode Consortium. 21*912701f9SAndroid Build Coastguard WorkerThis is not a stable document; it is inappropriate to cite this document as other than a work in progress._ --> 22*912701f9SAndroid Build Coastguard Worker 23*912701f9SAndroid Build Coastguard Worker_This document has been reviewed by Unicode members and other interested parties, and has been approved for publication by the Unicode Consortium. 24*912701f9SAndroid Build Coastguard WorkerThis is a stable document and may be used as reference material or cited as a normative reference by other specifications._ 25*912701f9SAndroid Build Coastguard Worker 26*912701f9SAndroid Build Coastguard Worker> _**A Unicode Technical Standard (UTS)** is an independent specification. Conformance to the Unicode Standard does not imply conformance to any UTS._ 27*912701f9SAndroid Build Coastguard Worker 28*912701f9SAndroid Build Coastguard Worker_Please submit corrigenda and other comments with the CLDR bug reporting form [[Bugs](tr35.md#Bugs)]. Related information that is useful in understanding this document is found in the [References](tr35.md#References). For the latest version of the Unicode Standard see [[Unicode](tr35.md#Unicode)]. For a list of current Unicode Technical Reports see [[Reports](tr35.md#Reports)]. For more information about versions of the Unicode Standard, see [[Versions](tr35.md#Versions)]._ 29*912701f9SAndroid Build Coastguard Worker 30*912701f9SAndroid Build Coastguard Worker## Parts 31*912701f9SAndroid Build Coastguard Worker 32*912701f9SAndroid Build Coastguard WorkerThe LDML specification is divided into the following parts: 33*912701f9SAndroid Build Coastguard Worker 34*912701f9SAndroid Build Coastguard Worker* Part 1: [Core](tr35.md#Contents) (languages, locales, basic structure) 35*912701f9SAndroid Build Coastguard Worker* Part 2: [General](tr35-general.md#Contents) (display names & transforms, etc.) 36*912701f9SAndroid Build Coastguard Worker* Part 3: [Numbers](tr35-numbers.md#Contents) (number & currency formatting) 37*912701f9SAndroid Build Coastguard Worker* Part 4: [Dates](tr35-dates.md#Contents) (date, time, time zone formatting) 38*912701f9SAndroid Build Coastguard Worker* Part 5: [Collation](tr35-collation.md#Contents) (sorting, searching, grouping) 39*912701f9SAndroid Build Coastguard Worker* Part 6: [Supplemental](tr35-info.md#Contents) (supplemental data) 40*912701f9SAndroid Build Coastguard Worker* Part 7: [Keyboards](tr35-keyboards.md#Contents) (keyboard mappings) 41*912701f9SAndroid Build Coastguard Worker* Part 8: [Person Names](tr35-personNames.md#Contents) (person names) 42*912701f9SAndroid Build Coastguard Worker* Part 9: [MessageFormat](tr35-messageFormat.md#Contents) (message format) 43*912701f9SAndroid Build Coastguard Worker 44*912701f9SAndroid Build Coastguard Worker## <a name="Contents">Contents of Part 9, Message Format</a> 45*912701f9SAndroid Build Coastguard Worker 46*912701f9SAndroid Build Coastguard Worker* [Introduction](#introduction) 47*912701f9SAndroid Build Coastguard Worker * [Conformance](#conformance) 48*912701f9SAndroid Build Coastguard Worker * [Terminology and Conventions](#terminology-and-conventions) 49*912701f9SAndroid Build Coastguard Worker * [Stability Policy](#stability-policy) 50*912701f9SAndroid Build Coastguard Worker* [Syntax](#syntax) 51*912701f9SAndroid Build Coastguard Worker * [Design Goals](#design-goals) 52*912701f9SAndroid Build Coastguard Worker * [Design Restrictions](#design-restrictions) 53*912701f9SAndroid Build Coastguard Worker * [Messages and their Syntax](#messages-and-their-syntax) 54*912701f9SAndroid Build Coastguard Worker * [Well-formed vs. Valid Messages](#well-formed-vs.-valid-messages) 55*912701f9SAndroid Build Coastguard Worker * [The Message](#the-message) 56*912701f9SAndroid Build Coastguard Worker * [Declarations](#declarations) 57*912701f9SAndroid Build Coastguard Worker * [Reserved Statements](#reserved-statements) 58*912701f9SAndroid Build Coastguard Worker * [Complex Body](#complex-body) 59*912701f9SAndroid Build Coastguard Worker * [Pattern](#pattern) 60*912701f9SAndroid Build Coastguard Worker * [Quoted Pattern](#quoted-pattern) 61*912701f9SAndroid Build Coastguard Worker * [Text](#text) 62*912701f9SAndroid Build Coastguard Worker * [Placeholder](#placeholder) 63*912701f9SAndroid Build Coastguard Worker * [Matcher](#matcher) 64*912701f9SAndroid Build Coastguard Worker * [Selector](#selector) 65*912701f9SAndroid Build Coastguard Worker * [Variant](#variant) 66*912701f9SAndroid Build Coastguard Worker * [Key](#key) 67*912701f9SAndroid Build Coastguard Worker * [Expressions](#expressions) 68*912701f9SAndroid Build Coastguard Worker * [Annotation](#annotation) 69*912701f9SAndroid Build Coastguard Worker * [Function](#function) 70*912701f9SAndroid Build Coastguard Worker * [Options](#options) 71*912701f9SAndroid Build Coastguard Worker * [Private-Use Annotations](#private-use-annotations) 72*912701f9SAndroid Build Coastguard Worker * [Reserved Annotations](#reserved-annotations) 73*912701f9SAndroid Build Coastguard Worker * [Markup](#markup) 74*912701f9SAndroid Build Coastguard Worker * [Attributes](#attributes) 75*912701f9SAndroid Build Coastguard Worker * [Other Syntax Elements](#other-syntax-elements) 76*912701f9SAndroid Build Coastguard Worker * [Keywords](#keywords) 77*912701f9SAndroid Build Coastguard Worker * [Literals](#literals) 78*912701f9SAndroid Build Coastguard Worker * [Names and Identifiers](#names-and-identifiers) 79*912701f9SAndroid Build Coastguard Worker * [Escape Sequences](#escape-sequences) 80*912701f9SAndroid Build Coastguard Worker * [Whitespace](#whitespace) 81*912701f9SAndroid Build Coastguard Worker* [Complete ABNF](#complete-abnf) 82*912701f9SAndroid Build Coastguard Worker * [`message.abnf`](#message.abnf) 83*912701f9SAndroid Build Coastguard Worker* [Errors](#errors) 84*912701f9SAndroid Build Coastguard Worker * [Error Handling](#error-handling) 85*912701f9SAndroid Build Coastguard Worker * [Syntax Errors](#syntax-errors) 86*912701f9SAndroid Build Coastguard Worker * [Data Model Errors](#data-model-errors) 87*912701f9SAndroid Build Coastguard Worker * [Variant Key Mismatch](#variant-key-mismatch) 88*912701f9SAndroid Build Coastguard Worker * [Missing Fallback Variant](#missing-fallback-variant) 89*912701f9SAndroid Build Coastguard Worker * [Missing Selector Annotation](#missing-selector-annotation) 90*912701f9SAndroid Build Coastguard Worker * [Duplicate Declaration](#duplicate-declaration) 91*912701f9SAndroid Build Coastguard Worker * [Duplicate Option Name](#duplicate-option-name) 92*912701f9SAndroid Build Coastguard Worker * [Resolution Errors](#resolution-errors) 93*912701f9SAndroid Build Coastguard Worker * [Unresolved Variable](#unresolved-variable) 94*912701f9SAndroid Build Coastguard Worker * [Unknown Function](#unknown-function) 95*912701f9SAndroid Build Coastguard Worker * [Unsupported Expression](#unsupported-expression) 96*912701f9SAndroid Build Coastguard Worker * [Invalid Expression](#invalid-expression) 97*912701f9SAndroid Build Coastguard Worker * [Unsupported Statement](#unsupported-statement) 98*912701f9SAndroid Build Coastguard Worker * [Selection Errors](#selection-errors) 99*912701f9SAndroid Build Coastguard Worker * [Formatting Errors](#formatting-errors) 100*912701f9SAndroid Build Coastguard Worker* [Function Registry](#function-registry) 101*912701f9SAndroid Build Coastguard Worker * [Goals](#goals) 102*912701f9SAndroid Build Coastguard Worker * [Conformance and Use](#conformance-and-use) 103*912701f9SAndroid Build Coastguard Worker * [Registry Data Model](#registry-data-model) 104*912701f9SAndroid Build Coastguard Worker * [Example](#example) 105*912701f9SAndroid Build Coastguard Worker * [Default Registry](#default-registry) 106*912701f9SAndroid Build Coastguard Worker * [String Value Selection and Formatting](#string-value-selection-and-formatting) 107*912701f9SAndroid Build Coastguard Worker * [The `:string` function](#the-string-function) 108*912701f9SAndroid Build Coastguard Worker * [Operands](#operands) 109*912701f9SAndroid Build Coastguard Worker * [Options](#options) 110*912701f9SAndroid Build Coastguard Worker * [Selection](#selection) 111*912701f9SAndroid Build Coastguard Worker * [Formatting](#formatting) 112*912701f9SAndroid Build Coastguard Worker * [Numeric Value Selection and Formatting](#numeric-value-selection-and-formatting) 113*912701f9SAndroid Build Coastguard Worker * [The `:number` function](#the-number-function) 114*912701f9SAndroid Build Coastguard Worker * [Operands](#operands) 115*912701f9SAndroid Build Coastguard Worker * [Options](#options) 116*912701f9SAndroid Build Coastguard Worker * [Default Value of `select` Option](#default-value-of-select-option) 117*912701f9SAndroid Build Coastguard Worker * [Percent Style](#percent-style) 118*912701f9SAndroid Build Coastguard Worker * [Selection](#selection) 119*912701f9SAndroid Build Coastguard Worker * [The `:integer` function](#the-integer-function) 120*912701f9SAndroid Build Coastguard Worker * [Operands](#operands) 121*912701f9SAndroid Build Coastguard Worker * [Options](#options) 122*912701f9SAndroid Build Coastguard Worker * [Default Value of `select` Option](#default-value-of-select-option) 123*912701f9SAndroid Build Coastguard Worker * [Percent Style](#percent-style) 124*912701f9SAndroid Build Coastguard Worker * [Selection](#selection) 125*912701f9SAndroid Build Coastguard Worker * [Number Operands](#number-operands) 126*912701f9SAndroid Build Coastguard Worker * [Digit Size Options](#digit-size-options) 127*912701f9SAndroid Build Coastguard Worker * [Number Selection](#number-selection) 128*912701f9SAndroid Build Coastguard Worker * [Rule Selection](#rule-selection) 129*912701f9SAndroid Build Coastguard Worker * [Determining Exact Literal Match](#determining-exact-literal-match) 130*912701f9SAndroid Build Coastguard Worker * [Date and Time Value Formatting](#date-and-time-value-formatting) 131*912701f9SAndroid Build Coastguard Worker * [The `:datetime` function](#the-datetime-function) 132*912701f9SAndroid Build Coastguard Worker * [Operands](#operands) 133*912701f9SAndroid Build Coastguard Worker * [Options](#options) 134*912701f9SAndroid Build Coastguard Worker * [The `:date` function](#the-date-function) 135*912701f9SAndroid Build Coastguard Worker * [Operands](#operands) 136*912701f9SAndroid Build Coastguard Worker * [Options](#options) 137*912701f9SAndroid Build Coastguard Worker * [The `:time` function](#the-time-function) 138*912701f9SAndroid Build Coastguard Worker * [Operands](#operands) 139*912701f9SAndroid Build Coastguard Worker * [Options](#options) 140*912701f9SAndroid Build Coastguard Worker * [Date and Time Operands](#date-and-time-operands) 141*912701f9SAndroid Build Coastguard Worker* [Formatting](#formatting) 142*912701f9SAndroid Build Coastguard Worker * [Formatting Context](#formatting-context) 143*912701f9SAndroid Build Coastguard Worker * [Expression and Markup Resolution](#expression-and-markup-resolution) 144*912701f9SAndroid Build Coastguard Worker * [Literal Resolution](#literal-resolution) 145*912701f9SAndroid Build Coastguard Worker * [Variable Resolution](#variable-resolution) 146*912701f9SAndroid Build Coastguard Worker * [Function Resolution](#function-resolution) 147*912701f9SAndroid Build Coastguard Worker * [Option Resolution](#option-resolution) 148*912701f9SAndroid Build Coastguard Worker * [Markup Resolution](#markup-resolution) 149*912701f9SAndroid Build Coastguard Worker * [Fallback Resolution](#fallback-resolution) 150*912701f9SAndroid Build Coastguard Worker * [Pattern Selection](#pattern-selection) 151*912701f9SAndroid Build Coastguard Worker * [Resolve Selectors](#resolve-selectors) 152*912701f9SAndroid Build Coastguard Worker * [Resolve Preferences](#resolve-preferences) 153*912701f9SAndroid Build Coastguard Worker * [Filter Variants](#filter-variants) 154*912701f9SAndroid Build Coastguard Worker * [Sort Variants](#sort-variants) 155*912701f9SAndroid Build Coastguard Worker * [Examples](#examples) 156*912701f9SAndroid Build Coastguard Worker * [Example 1](#example-1) 157*912701f9SAndroid Build Coastguard Worker * [Example 2](#example-2) 158*912701f9SAndroid Build Coastguard Worker * [Example 3](#example-3) 159*912701f9SAndroid Build Coastguard Worker * [Formatting](#formatting) 160*912701f9SAndroid Build Coastguard Worker * [Examples](#examples) 161*912701f9SAndroid Build Coastguard Worker * [Formatting Fallback Values](#formatting-fallback-values) 162*912701f9SAndroid Build Coastguard Worker * [Handling Bidirectional Text](#handling-bidirectional-text) 163*912701f9SAndroid Build Coastguard Worker* [Interchange Data Model](#interchange-data-model) 164*912701f9SAndroid Build Coastguard Worker * [Messages](#messages) 165*912701f9SAndroid Build Coastguard Worker * [Patterns](#patterns) 166*912701f9SAndroid Build Coastguard Worker * [Expressions](#expressions) 167*912701f9SAndroid Build Coastguard Worker * [Markup](#markup) 168*912701f9SAndroid Build Coastguard Worker * [Extensions](#extensions) 169*912701f9SAndroid Build Coastguard Worker* [Appendices](#appendices) 170*912701f9SAndroid Build Coastguard Worker * [Security Considerations](#security-considerations) 171*912701f9SAndroid Build Coastguard Worker * [Acknowledgements](#acknowledgements) 172*912701f9SAndroid Build Coastguard Worker 173*912701f9SAndroid Build Coastguard Worker## Introduction 174*912701f9SAndroid Build Coastguard Worker 175*912701f9SAndroid Build Coastguard WorkerOne of the challenges in adapting software to work for 176*912701f9SAndroid Build Coastguard Workerusers with different languages and cultures is the need for **_dynamic messages_**. 177*912701f9SAndroid Build Coastguard WorkerWhenever a user interface needs to present data as part of a larger string, 178*912701f9SAndroid Build Coastguard Workerthat data needs to be formatted (and the message may need to be altered) 179*912701f9SAndroid Build Coastguard Workerto make it culturally accepted and grammatically correct. 180*912701f9SAndroid Build Coastguard Worker 181*912701f9SAndroid Build Coastguard Worker> For example, if your US English (`en-US`) interface has a message like: 182*912701f9SAndroid Build Coastguard Worker> 183*912701f9SAndroid Build Coastguard Worker> > Your item had 1,023 views on April 3, 2023 184*912701f9SAndroid Build Coastguard Worker> 185*912701f9SAndroid Build Coastguard Worker> You want the translated message to be appropriately formatted into French: 186*912701f9SAndroid Build Coastguard Worker> 187*912701f9SAndroid Build Coastguard Worker> > Votre article a eu 1 023 vues le 3 avril 2023 188*912701f9SAndroid Build Coastguard Worker> 189*912701f9SAndroid Build Coastguard Worker> Or Japanese: 190*912701f9SAndroid Build Coastguard Worker> 191*912701f9SAndroid Build Coastguard Worker> > あなたのアイテムは 2023 年 4 月 3 日に 1,023 回閲覧されました。 192*912701f9SAndroid Build Coastguard Worker 193*912701f9SAndroid Build Coastguard WorkerThis specification defines the 194*912701f9SAndroid Build Coastguard Workerdata model, syntax, processing, and conformance requirements 195*912701f9SAndroid Build Coastguard Workerfor the next generation of _dynamic messages_. 196*912701f9SAndroid Build Coastguard WorkerIt is intended for adoption by programming languages and APIs. 197*912701f9SAndroid Build Coastguard WorkerThis will enable the integration of 198*912701f9SAndroid Build Coastguard Workerexisting internationalization APIs (such as the date and number formats shown above), 199*912701f9SAndroid Build Coastguard Workergrammatical matching (such as plurals or genders), 200*912701f9SAndroid Build Coastguard Workeras well as user-defined formats and message selectors. 201*912701f9SAndroid Build Coastguard Worker 202*912701f9SAndroid Build Coastguard WorkerThe document is the successor to ICU MessageFormat, 203*912701f9SAndroid Build Coastguard Workerhenceforth called ICU MessageFormat 1.0. 204*912701f9SAndroid Build Coastguard Worker 205*912701f9SAndroid Build Coastguard Worker### Conformance 206*912701f9SAndroid Build Coastguard Worker 207*912701f9SAndroid Build Coastguard WorkerEverything in this specification is normative except for: 208*912701f9SAndroid Build Coastguard Workersections marked as non-normative, 209*912701f9SAndroid Build Coastguard Workerall authoring guidelines, diagrams, examples, and notes. 210*912701f9SAndroid Build Coastguard Worker 211*912701f9SAndroid Build Coastguard WorkerThe key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL 212*912701f9SAndroid Build Coastguard WorkerNOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", 213*912701f9SAndroid Build Coastguard Worker"MAY", and "OPTIONAL" in this document are to be interpreted as 214*912701f9SAndroid Build Coastguard Workerdescribed in BCP 14 \[[RFC2119](https://www.rfc-editor.org/rfc/rfc2119)\] 215*912701f9SAndroid Build Coastguard Worker\[[RFC8174](https://www.rfc-editor.org/rfc/rfc8174)\] when, and only when, they 216*912701f9SAndroid Build Coastguard Workerappear in all capitals, as shown here. 217*912701f9SAndroid Build Coastguard Worker 218*912701f9SAndroid Build Coastguard Worker### Terminology and Conventions 219*912701f9SAndroid Build Coastguard Worker 220*912701f9SAndroid Build Coastguard WorkerA **_term_** looks like this when it is defined in this specification. 221*912701f9SAndroid Build Coastguard Worker 222*912701f9SAndroid Build Coastguard WorkerA reference to a _term_ looks like this. 223*912701f9SAndroid Build Coastguard Worker 224*912701f9SAndroid Build Coastguard Worker> Examples are non-normative and styled like this. 225*912701f9SAndroid Build Coastguard Worker 226*912701f9SAndroid Build Coastguard Worker### Stability Policy 227*912701f9SAndroid Build Coastguard Worker 228*912701f9SAndroid Build Coastguard Worker> [!IMPORTANT] 229*912701f9SAndroid Build Coastguard Worker> The provisions of the stability policy are not in effect until 230*912701f9SAndroid Build Coastguard Worker> the conclusion of the technical preview and adoption of this specification. 231*912701f9SAndroid Build Coastguard Worker 232*912701f9SAndroid Build Coastguard WorkerUpdates to this specification will not change 233*912701f9SAndroid Build Coastguard Workerthe syntactical meaning, the runtime output, or other behaviour 234*912701f9SAndroid Build Coastguard Workerof valid messages written for earlier versions of this specification 235*912701f9SAndroid Build Coastguard Workerthat only use functions defined in this specification. 236*912701f9SAndroid Build Coastguard WorkerUpdates to this specification will not remove any syntax provided in this version. 237*912701f9SAndroid Build Coastguard WorkerFuture versions MAY add additional structure or meaning to existing syntax. 238*912701f9SAndroid Build Coastguard Worker 239*912701f9SAndroid Build Coastguard WorkerUpdates to this specification will not remove any reserved keywords or sigils. 240*912701f9SAndroid Build Coastguard Worker 241*912701f9SAndroid Build Coastguard Worker> [!NOTE] 242*912701f9SAndroid Build Coastguard Worker> Future versions may define new keywords. 243*912701f9SAndroid Build Coastguard Worker 244*912701f9SAndroid Build Coastguard WorkerUpdates to this specification will not reserve or assign meaning to 245*912701f9SAndroid Build Coastguard Workerany character "sigils" except for those in the `reserved` production. 246*912701f9SAndroid Build Coastguard Worker 247*912701f9SAndroid Build Coastguard WorkerUpdates to this specification 248*912701f9SAndroid Build Coastguard Workerwill not remove any functions defined in the default registry nor 249*912701f9SAndroid Build Coastguard Workerwill they remove any options or option values. 250*912701f9SAndroid Build Coastguard WorkerAdditional options or option values MAY be defined. 251*912701f9SAndroid Build Coastguard Worker 252*912701f9SAndroid Build Coastguard Worker> [!NOTE] 253*912701f9SAndroid Build Coastguard Worker> This does not guarantee that the results of formatting will never change. 254*912701f9SAndroid Build Coastguard Worker> Even when the specification doesn't change, 255*912701f9SAndroid Build Coastguard Worker> the functions for date formatting, number formatting and so on 256*912701f9SAndroid Build Coastguard Worker> will change their results over time. 257*912701f9SAndroid Build Coastguard Worker 258*912701f9SAndroid Build Coastguard WorkerLater specification versions MAY make previously invalid messages valid. 259*912701f9SAndroid Build Coastguard Worker 260*912701f9SAndroid Build Coastguard WorkerUpdates to this specification will not introduce message syntax that, 261*912701f9SAndroid Build Coastguard Workerwhen parsed according to earlier versions of this specification, 262*912701f9SAndroid Build Coastguard Workerwould produce syntax or data model errors. 263*912701f9SAndroid Build Coastguard WorkerSuch messages MAY produce errors when formatted 264*912701f9SAndroid Build Coastguard Workeraccording to an earlier version of this specification. 265*912701f9SAndroid Build Coastguard Worker 266*912701f9SAndroid Build Coastguard WorkerFrom version 2.0, MessageFormat will only reserve, define, or require 267*912701f9SAndroid Build Coastguard Workerfunction names or function option names 268*912701f9SAndroid Build Coastguard Workerconsisting of characters in the ranges a-z, A-Z, and 0-9. 269*912701f9SAndroid Build Coastguard WorkerAll other names in these categories are reserved for the use of implementations or users. 270*912701f9SAndroid Build Coastguard Worker 271*912701f9SAndroid Build Coastguard Worker> [!NOTE] 272*912701f9SAndroid Build Coastguard Worker> Users defining custom names SHOULD include at least one character outside these ranges 273*912701f9SAndroid Build Coastguard Worker> to ensure that they will be compatible with future versions of this specification. 274*912701f9SAndroid Build Coastguard Worker 275*912701f9SAndroid Build Coastguard WorkerLater versions of this specification will not introduce changes 276*912701f9SAndroid Build Coastguard Workerto the data model that would result in a data model representation 277*912701f9SAndroid Build Coastguard Workerbased on this version being invalid. 278*912701f9SAndroid Build Coastguard Worker 279*912701f9SAndroid Build Coastguard Worker> For example, existing interfaces or fields will not be removed. 280*912701f9SAndroid Build Coastguard Worker 281*912701f9SAndroid Build Coastguard WorkerLater versions of this specification MAY introduce changes 282*912701f9SAndroid Build Coastguard Workerto the data model that would result in future data model representations 283*912701f9SAndroid Build Coastguard Workernot being valid for implementations of this version of the data model. 284*912701f9SAndroid Build Coastguard Worker 285*912701f9SAndroid Build Coastguard Worker> For example, a future version could introduce a new keyword, 286*912701f9SAndroid Build Coastguard Worker> whose data model representation would be a new interface 287*912701f9SAndroid Build Coastguard Worker> that is not recognized by this version's data model. 288*912701f9SAndroid Build Coastguard Worker 289*912701f9SAndroid Build Coastguard WorkerLater specification versions will not introduce syntax that cannot be 290*912701f9SAndroid Build Coastguard Workerrepresented by this version of the data model. 291*912701f9SAndroid Build Coastguard Worker 292*912701f9SAndroid Build Coastguard Worker> For example, a future version could introduce a new keyword. 293*912701f9SAndroid Build Coastguard Worker> The future version's data model would provide an interface for that keyword 294*912701f9SAndroid Build Coastguard Worker> while this version of the data model would parse the value into 295*912701f9SAndroid Build Coastguard Worker> the interface `UnsupportedStatement`. 296*912701f9SAndroid Build Coastguard Worker> Both data models would be "valid" in their context, 297*912701f9SAndroid Build Coastguard Worker> but this version's would be missing any functionality for the new statement type. 298*912701f9SAndroid Build Coastguard Worker 299*912701f9SAndroid Build Coastguard Worker## Syntax 300*912701f9SAndroid Build Coastguard Worker 301*912701f9SAndroid Build Coastguard WorkerThis section defines the formal grammar describing the syntax of a single message. 302*912701f9SAndroid Build Coastguard Worker 303*912701f9SAndroid Build Coastguard Worker### Design Goals 304*912701f9SAndroid Build Coastguard Worker 305*912701f9SAndroid Build Coastguard Worker_This section is non-normative._ 306*912701f9SAndroid Build Coastguard Worker 307*912701f9SAndroid Build Coastguard WorkerThe design goals of the syntax specification are as follows: 308*912701f9SAndroid Build Coastguard Worker 309*912701f9SAndroid Build Coastguard Worker1. The syntax should leverage the familiarity with ICU MessageFormat 1.0 310*912701f9SAndroid Build Coastguard Worker in order to lower the barrier to entry and increase the chance of adoption. 311*912701f9SAndroid Build Coastguard Worker At the same time, 312*912701f9SAndroid Build Coastguard Worker the syntax should fix the [pain points of ICU MessageFormat 1.0](https://github.com/unicode-org/message-format-wg/blob/main/docs/why_mf_next.md). 313*912701f9SAndroid Build Coastguard Worker 314*912701f9SAndroid Build Coastguard Worker - _Non-Goal_: Be backwards-compatible with the ICU MessageFormat 1.0 syntax. 315*912701f9SAndroid Build Coastguard Worker 316*912701f9SAndroid Build Coastguard Worker1. The syntax inside translatable content should be easy to understand for humans. 317*912701f9SAndroid Build Coastguard Worker This includes making it clear which parts of the message body _are_ translatable content, 318*912701f9SAndroid Build Coastguard Worker which parts inside it are placeholders for expressions, 319*912701f9SAndroid Build Coastguard Worker as well as making the selection logic predictable and easy to reason about. 320*912701f9SAndroid Build Coastguard Worker 321*912701f9SAndroid Build Coastguard Worker - _Non-Goal_: Make the syntax intuitive enough for non-technical translators to hand-edit. 322*912701f9SAndroid Build Coastguard Worker Instead, we assume that most translators will work with MessageFormat 2 323*912701f9SAndroid Build Coastguard Worker by means of GUI tooling, CAT workbenches etc. 324*912701f9SAndroid Build Coastguard Worker 325*912701f9SAndroid Build Coastguard Worker1. The syntax surrounding translatable content should be easy to write and edit 326*912701f9SAndroid Build Coastguard Worker for developers, localization engineers, and easy to parse by machines. 327*912701f9SAndroid Build Coastguard Worker 328*912701f9SAndroid Build Coastguard Worker1. The syntax should make a single message easily embeddable inside many container formats: 329*912701f9SAndroid Build Coastguard Worker `.properties`, YAML, XML, inlined as string literals in programming languages, etc. 330*912701f9SAndroid Build Coastguard Worker This includes a future _MessageResource_ specification. 331*912701f9SAndroid Build Coastguard Worker 332*912701f9SAndroid Build Coastguard Worker - _Non-Goal_: Support unnecessary escape sequences, which would theirselves require 333*912701f9SAndroid Build Coastguard Worker additional escaping when embedded. Instead, we tolerate direct use of nearly all 334*912701f9SAndroid Build Coastguard Worker characters (including line breaks, control characters, etc.) and rely upon escaping 335*912701f9SAndroid Build Coastguard Worker in those outer formats to aid human comprehension (e.g., depending upon container 336*912701f9SAndroid Build Coastguard Worker format, a U+000A LINE FEED might be represented as `\n`, `\012`, `\x0A`, `\u000A`, 337*912701f9SAndroid Build Coastguard Worker `\U0000000A`, `
`, `
`, `%0A`, `<LF>`, or something else entirely). 338*912701f9SAndroid Build Coastguard Worker 339*912701f9SAndroid Build Coastguard Worker### Design Restrictions 340*912701f9SAndroid Build Coastguard Worker 341*912701f9SAndroid Build Coastguard Worker_This section is non-normative._ 342*912701f9SAndroid Build Coastguard Worker 343*912701f9SAndroid Build Coastguard WorkerThe syntax specification takes into account the following design restrictions: 344*912701f9SAndroid Build Coastguard Worker 345*912701f9SAndroid Build Coastguard Worker1. Whitespace outside the translatable content should be insignificant. 346*912701f9SAndroid Build Coastguard Worker It should be possible to define a message entirely on a single line with no ambiguity, 347*912701f9SAndroid Build Coastguard Worker as well as to format it over multiple lines for clarity. 348*912701f9SAndroid Build Coastguard Worker 349*912701f9SAndroid Build Coastguard Worker1. The syntax should define as few special characters and sigils as possible. 350*912701f9SAndroid Build Coastguard Worker Note that this necessitates extra care when presenting messages for human consumption, 351*912701f9SAndroid Build Coastguard Worker because they may contain invisible characters such as U+200B ZERO WIDTH SPACE, 352*912701f9SAndroid Build Coastguard Worker control characters such as U+0000 NULL and U+0009 TAB, permanently reserved noncharacters 353*912701f9SAndroid Build Coastguard Worker (U+FDD0 through U+FDEF and U+<i>n</i>FFFE and U+<i>n</i>FFFF where <i>n</i> is 0x0 through 0x10), 354*912701f9SAndroid Build Coastguard Worker private-use code points (U+E000 through U+F8FF, U+F0000 through U+FFFFD, and 355*912701f9SAndroid Build Coastguard Worker U+100000 through U+10FFFD), unassigned code points, and other potentially confusing content. 356*912701f9SAndroid Build Coastguard Worker 357*912701f9SAndroid Build Coastguard Worker### Messages and their Syntax 358*912701f9SAndroid Build Coastguard Worker 359*912701f9SAndroid Build Coastguard WorkerThe purpose of MessageFormat is to allow content to vary at runtime. 360*912701f9SAndroid Build Coastguard WorkerThis variation might be due to placing a value into the content 361*912701f9SAndroid Build Coastguard Workeror it might be due to selecting a different bit of content based on some data value 362*912701f9SAndroid Build Coastguard Workeror it might be due to a combination of the two. 363*912701f9SAndroid Build Coastguard Worker 364*912701f9SAndroid Build Coastguard WorkerMessageFormat calls the template for a given formatting operation a _message_. 365*912701f9SAndroid Build Coastguard Worker 366*912701f9SAndroid Build Coastguard WorkerThe values passed in at runtime (which are to be placed into the content or used 367*912701f9SAndroid Build Coastguard Workerto select between different content items) are called _external variables_. 368*912701f9SAndroid Build Coastguard WorkerThe author of a _message_ can also assign _local variables_, including 369*912701f9SAndroid Build Coastguard Workervariables that modify _external variables_. 370*912701f9SAndroid Build Coastguard Worker 371*912701f9SAndroid Build Coastguard WorkerThis part of the MessageFormat specification defines the syntax for a _message_, 372*912701f9SAndroid Build Coastguard Workeralong with the concepts and terminology needed when processing a _message_ 373*912701f9SAndroid Build Coastguard Workerduring the [formatting](#formatting) of a _message_ at runtime. 374*912701f9SAndroid Build Coastguard Worker 375*912701f9SAndroid Build Coastguard WorkerThe complete formal syntax of a _message_ is described by the [ABNF](#complete-abnf). 376*912701f9SAndroid Build Coastguard Worker 377*912701f9SAndroid Build Coastguard Worker#### Well-formed vs. Valid Messages 378*912701f9SAndroid Build Coastguard Worker 379*912701f9SAndroid Build Coastguard WorkerA _message_ is **_<dfn>well-formed</dfn>_** if it satisfies all the rules of the grammar. 380*912701f9SAndroid Build Coastguard WorkerAttempting to parse a _message_ that is not _well-formed_ will result in a _Syntax Error_. 381*912701f9SAndroid Build Coastguard Worker 382*912701f9SAndroid Build Coastguard WorkerA _message_ is **_<dfn>valid</dfn>_** if it is _well-formed_ and 383*912701f9SAndroid Build Coastguard Worker**also** meets the additional content restrictions 384*912701f9SAndroid Build Coastguard Workerand semantic requirements about its structure defined below for 385*912701f9SAndroid Build Coastguard Worker_declarations_, _matcher_ and _options_. 386*912701f9SAndroid Build Coastguard WorkerAttempting to parse a _message_ that is not _valid_ will result in a _Data Model Error_. 387*912701f9SAndroid Build Coastguard Worker 388*912701f9SAndroid Build Coastguard Worker### The Message 389*912701f9SAndroid Build Coastguard Worker 390*912701f9SAndroid Build Coastguard WorkerA **_<dfn>message</dfn>_** is the complete template for a specific message formatting request. 391*912701f9SAndroid Build Coastguard Worker 392*912701f9SAndroid Build Coastguard Worker> [!NOTE] 393*912701f9SAndroid Build Coastguard Worker> This syntax is designed to be embeddable into many different programming languages and formats. 394*912701f9SAndroid Build Coastguard Worker> As such, it avoids constructs, such as character escapes, that are specific to any given file 395*912701f9SAndroid Build Coastguard Worker> format or processor. 396*912701f9SAndroid Build Coastguard Worker> In particular, it avoids using quote characters common to many file formats and formal languages 397*912701f9SAndroid Build Coastguard Worker> so that these do not need to be escaped in the body of a _message_. 398*912701f9SAndroid Build Coastguard Worker 399*912701f9SAndroid Build Coastguard Worker> [!NOTE] 400*912701f9SAndroid Build Coastguard Worker> In general (and except where required by the syntax), whitespace carries no meaning in the structure 401*912701f9SAndroid Build Coastguard Worker> of a _message_. While many of the examples in this spec are written on multiple lines, the formatting 402*912701f9SAndroid Build Coastguard Worker> shown is primarily for readability. 403*912701f9SAndroid Build Coastguard Worker> 404*912701f9SAndroid Build Coastguard Worker> > **Example** This _message_: 405*912701f9SAndroid Build Coastguard Worker> > 406*912701f9SAndroid Build Coastguard Worker> > ``` 407*912701f9SAndroid Build Coastguard Worker> > .local $foo = { |horse| } 408*912701f9SAndroid Build Coastguard Worker> > {{You have a {$foo}!}} 409*912701f9SAndroid Build Coastguard Worker> > ``` 410*912701f9SAndroid Build Coastguard Worker> > 411*912701f9SAndroid Build Coastguard Worker> > Can also be written as: 412*912701f9SAndroid Build Coastguard Worker> > 413*912701f9SAndroid Build Coastguard Worker> > ``` 414*912701f9SAndroid Build Coastguard Worker> > .local $foo={|horse|}{{You have a {$foo}!}} 415*912701f9SAndroid Build Coastguard Worker> > ``` 416*912701f9SAndroid Build Coastguard Worker> > 417*912701f9SAndroid Build Coastguard Worker> > An exception to this is: whitespace inside a _pattern_ is **always** significant. 418*912701f9SAndroid Build Coastguard Worker 419*912701f9SAndroid Build Coastguard Worker> [!NOTE] 420*912701f9SAndroid Build Coastguard Worker> The syntax assumes that each _message_ will be displayed with a left-to-right display order 421*912701f9SAndroid Build Coastguard Worker> and be processed in the logical character order. 422*912701f9SAndroid Build Coastguard Worker> The syntax also permits the use of right-to-left characters in _identifiers_, 423*912701f9SAndroid Build Coastguard Worker> _literals_, and other values. 424*912701f9SAndroid Build Coastguard Worker> This can result in confusion when viewing the _message_. 425*912701f9SAndroid Build Coastguard Worker> 426*912701f9SAndroid Build Coastguard Worker> Additional restrictions or requirements, 427*912701f9SAndroid Build Coastguard Worker> such as permitting the use of certain bidirectional control characters in the syntax, 428*912701f9SAndroid Build Coastguard Worker> might be added during the Tech Preview to better manage bidirectional text. 429*912701f9SAndroid Build Coastguard Worker> Feedback on the creation and management of _messages_ 430*912701f9SAndroid Build Coastguard Worker> containing bidirectional tokens is strongly desired. 431*912701f9SAndroid Build Coastguard Worker 432*912701f9SAndroid Build Coastguard WorkerA _message_ can be a _simple message_ or it can be a _complex message_. 433*912701f9SAndroid Build Coastguard Worker 434*912701f9SAndroid Build Coastguard Worker```abnf 435*912701f9SAndroid Build Coastguard Workermessage = simple-message / complex-message 436*912701f9SAndroid Build Coastguard Worker``` 437*912701f9SAndroid Build Coastguard Worker 438*912701f9SAndroid Build Coastguard WorkerA **_<dfn>simple message</dfn>_** contains a single _pattern_, 439*912701f9SAndroid Build Coastguard Workerwith restrictions on its first character. 440*912701f9SAndroid Build Coastguard WorkerAn empty string is a valid _simple message_. 441*912701f9SAndroid Build Coastguard Worker 442*912701f9SAndroid Build Coastguard Worker```abnf 443*912701f9SAndroid Build Coastguard Workersimple-message = [simple-start pattern] 444*912701f9SAndroid Build Coastguard Workersimple-start = simple-start-char / text-escape / placeholder 445*912701f9SAndroid Build Coastguard Worker``` 446*912701f9SAndroid Build Coastguard Worker 447*912701f9SAndroid Build Coastguard WorkerA **_<dfn>complex message</dfn>_** is any _message_ that contains _declarations_, 448*912701f9SAndroid Build Coastguard Workera _matcher_, or both. 449*912701f9SAndroid Build Coastguard WorkerA _complex message_ always begins with either a keyword that has a `.` prefix or a _quoted pattern_ 450*912701f9SAndroid Build Coastguard Workerand consists of: 451*912701f9SAndroid Build Coastguard Worker 452*912701f9SAndroid Build Coastguard Worker1. an optional list of _declarations_, followed by 453*912701f9SAndroid Build Coastguard Worker2. a _complex body_ 454*912701f9SAndroid Build Coastguard Worker 455*912701f9SAndroid Build Coastguard Worker```abnf 456*912701f9SAndroid Build Coastguard Workercomplex-message = *(declaration [s]) complex-body 457*912701f9SAndroid Build Coastguard Worker``` 458*912701f9SAndroid Build Coastguard Worker 459*912701f9SAndroid Build Coastguard Worker#### Declarations 460*912701f9SAndroid Build Coastguard Worker 461*912701f9SAndroid Build Coastguard WorkerA **_<dfn>declaration</dfn>_** binds a _variable_ identifier to a value within the scope of a _message_. 462*912701f9SAndroid Build Coastguard WorkerThis _variable_ can then be used in other _expressions_ within the same _message_. 463*912701f9SAndroid Build Coastguard Worker_Declarations_ are optional: many messages will not contain any _declarations_. 464*912701f9SAndroid Build Coastguard Worker 465*912701f9SAndroid Build Coastguard WorkerAn **_<dfn>input-declaration</dfn>_** binds a _variable_ to an external input value. 466*912701f9SAndroid Build Coastguard WorkerThe _variable-expression_ of an _input-declaration_ 467*912701f9SAndroid Build Coastguard WorkerMAY include an _annotation_ that is applied to the external value. 468*912701f9SAndroid Build Coastguard Worker 469*912701f9SAndroid Build Coastguard WorkerA **_<dfn>local-declaration</dfn>_** binds a _variable_ to the resolved value of an _expression_. 470*912701f9SAndroid Build Coastguard Worker 471*912701f9SAndroid Build Coastguard WorkerFor compatibility with later MessageFormat 2 specification versions, 472*912701f9SAndroid Build Coastguard Worker_declarations_ MAY also include _reserved statements_. 473*912701f9SAndroid Build Coastguard Worker 474*912701f9SAndroid Build Coastguard Worker```abnf 475*912701f9SAndroid Build Coastguard Workerdeclaration = input-declaration / local-declaration / reserved-statement 476*912701f9SAndroid Build Coastguard Workerinput-declaration = input [s] variable-expression 477*912701f9SAndroid Build Coastguard Workerlocal-declaration = local s variable [s] "=" [s] expression 478*912701f9SAndroid Build Coastguard Worker``` 479*912701f9SAndroid Build Coastguard Worker 480*912701f9SAndroid Build Coastguard Worker_Variables_, once declared, MUST NOT be redeclared. 481*912701f9SAndroid Build Coastguard WorkerA _message_ that does any of the following is not _valid_ and will produce a 482*912701f9SAndroid Build Coastguard Worker_Duplicate Declaration_ error during processing: 483*912701f9SAndroid Build Coastguard Worker- A _declaration_ MUST NOT bind a _variable_ 484*912701f9SAndroid Build Coastguard Worker that appears as a _variable_ anywhere within a previous _declaration_. 485*912701f9SAndroid Build Coastguard Worker- An _input-declaration_ MUST NOT bind a _variable_ 486*912701f9SAndroid Build Coastguard Worker that appears anywhere within the _annotation_ of its _variable-expression_. 487*912701f9SAndroid Build Coastguard Worker- A _local-declaration_ MUST NOT bind a _variable_ that appears in its _expression_. 488*912701f9SAndroid Build Coastguard Worker 489*912701f9SAndroid Build Coastguard WorkerA _local-declaration_ MAY overwrite an external input value as long as the 490*912701f9SAndroid Build Coastguard Workerexternal input value does not appear in a previous _declaration_. 491*912701f9SAndroid Build Coastguard Worker 492*912701f9SAndroid Build Coastguard Worker> [!NOTE] 493*912701f9SAndroid Build Coastguard Worker> These restrictions only apply to _declarations_. 494*912701f9SAndroid Build Coastguard Worker> A _placeholder_ or _selector_ can apply a different annotation to a _variable_ 495*912701f9SAndroid Build Coastguard Worker> than one applied to the same _variable_ named in a _declaration_. 496*912701f9SAndroid Build Coastguard Worker> For example, this message is _valid_: 497*912701f9SAndroid Build Coastguard Worker> ``` 498*912701f9SAndroid Build Coastguard Worker> .input {$var :number maximumFractionDigits=0} 499*912701f9SAndroid Build Coastguard Worker> .match {$var :number maximumFractionDigits=2} 500*912701f9SAndroid Build Coastguard Worker> 0 {{The selector can apply a different annotation to {$var} for the purposes of selection}} 501*912701f9SAndroid Build Coastguard Worker> * {{A placeholder in a pattern can apply a different annotation to {$var :number maximumFractionDigits=3}}} 502*912701f9SAndroid Build Coastguard Worker> ``` 503*912701f9SAndroid Build Coastguard Worker> (See the [Errors](#errors) section for examples of invalid messages) 504*912701f9SAndroid Build Coastguard Worker 505*912701f9SAndroid Build Coastguard Worker##### Reserved Statements 506*912701f9SAndroid Build Coastguard Worker 507*912701f9SAndroid Build Coastguard WorkerA **_<dfn>reserved statement</dfn>_** reserves additional `.keywords` 508*912701f9SAndroid Build Coastguard Workerfor use by future versions of this specification. 509*912701f9SAndroid Build Coastguard WorkerAny such future keyword must start with `.`, 510*912701f9SAndroid Build Coastguard Workerfollowed by two or more lower-case ASCII characters. 511*912701f9SAndroid Build Coastguard Worker 512*912701f9SAndroid Build Coastguard WorkerThe rest of the statement supports 513*912701f9SAndroid Build Coastguard Workera similarly wide range of content as _reserved annotations_, 514*912701f9SAndroid Build Coastguard Workerbut it MUST end with one or more _expressions_. 515*912701f9SAndroid Build Coastguard Worker 516*912701f9SAndroid Build Coastguard Worker```abnf 517*912701f9SAndroid Build Coastguard Workerreserved-statement = reserved-keyword [s reserved-body] 1*([s] expression) 518*912701f9SAndroid Build Coastguard Workerreserved-keyword = "." name 519*912701f9SAndroid Build Coastguard Worker``` 520*912701f9SAndroid Build Coastguard Worker 521*912701f9SAndroid Build Coastguard Worker> [!NOTE] 522*912701f9SAndroid Build Coastguard Worker> The `reserved-keyword` ABNF rule is a simplification, 523*912701f9SAndroid Build Coastguard Worker> as it MUST NOT be considered to match any of the existing keywords 524*912701f9SAndroid Build Coastguard Worker> `.input`, `.local`, or `.match`. 525*912701f9SAndroid Build Coastguard Worker 526*912701f9SAndroid Build Coastguard WorkerThis allows flexibility in future standardization, 527*912701f9SAndroid Build Coastguard Workeras future definitions MAY define additional semantics and constraints 528*912701f9SAndroid Build Coastguard Workeron the contents of these _reserved statements_. 529*912701f9SAndroid Build Coastguard Worker 530*912701f9SAndroid Build Coastguard WorkerImplementations MUST NOT assign meaning or semantics to a _reserved statement_: 531*912701f9SAndroid Build Coastguard Workerthese are reserved for future standardization. 532*912701f9SAndroid Build Coastguard WorkerImplementations MUST NOT remove or alter the contents of a _reserved statement_. 533*912701f9SAndroid Build Coastguard Worker 534*912701f9SAndroid Build Coastguard Worker#### Complex Body 535*912701f9SAndroid Build Coastguard Worker 536*912701f9SAndroid Build Coastguard WorkerThe **_<dfn>complex body</dfn>_** of a _complex message_ is the part that will be formatted. 537*912701f9SAndroid Build Coastguard WorkerThe _complex body_ consists of either a _quoted pattern_ or a _matcher_. 538*912701f9SAndroid Build Coastguard Worker 539*912701f9SAndroid Build Coastguard Worker```abnf 540*912701f9SAndroid Build Coastguard Workercomplex-body = quoted-pattern / matcher 541*912701f9SAndroid Build Coastguard Worker``` 542*912701f9SAndroid Build Coastguard Worker 543*912701f9SAndroid Build Coastguard Worker### Pattern 544*912701f9SAndroid Build Coastguard Worker 545*912701f9SAndroid Build Coastguard WorkerA **_<dfn>pattern</dfn>_** contains a sequence of _text_ and _placeholders_ to be formatted as a unit. 546*912701f9SAndroid Build Coastguard WorkerUnless there is an error, resolving a _message_ always results in the formatting 547*912701f9SAndroid Build Coastguard Workerof a single _pattern_. 548*912701f9SAndroid Build Coastguard Worker 549*912701f9SAndroid Build Coastguard Worker```abnf 550*912701f9SAndroid Build Coastguard Workerpattern = *(text-char / text-escape / placeholder) 551*912701f9SAndroid Build Coastguard Worker``` 552*912701f9SAndroid Build Coastguard WorkerA _pattern_ MAY be empty. 553*912701f9SAndroid Build Coastguard Worker 554*912701f9SAndroid Build Coastguard WorkerA _pattern_ MAY contain an arbitrary number of _placeholders_ to be evaluated 555*912701f9SAndroid Build Coastguard Workerduring the formatting process. 556*912701f9SAndroid Build Coastguard Worker 557*912701f9SAndroid Build Coastguard Worker#### Quoted Pattern 558*912701f9SAndroid Build Coastguard Worker 559*912701f9SAndroid Build Coastguard WorkerA **_<dfn>quoted pattern</dfn>_** is a _pattern_ that is "quoted" to prevent 560*912701f9SAndroid Build Coastguard Workerinterference with other parts of the _message_. 561*912701f9SAndroid Build Coastguard WorkerA _quoted pattern_ starts with a sequence of two U+007B LEFT CURLY BRACKET `{{` 562*912701f9SAndroid Build Coastguard Workerand ends with a sequence of two U+007D RIGHT CURLY BRACKET `}}`. 563*912701f9SAndroid Build Coastguard Worker 564*912701f9SAndroid Build Coastguard Worker```abnf 565*912701f9SAndroid Build Coastguard Workerquoted-pattern = "{{" pattern "}}" 566*912701f9SAndroid Build Coastguard Worker``` 567*912701f9SAndroid Build Coastguard Worker 568*912701f9SAndroid Build Coastguard WorkerA _quoted pattern_ MAY be empty. 569*912701f9SAndroid Build Coastguard Worker 570*912701f9SAndroid Build Coastguard Worker> An empty _quoted pattern_: 571*912701f9SAndroid Build Coastguard Worker> 572*912701f9SAndroid Build Coastguard Worker> ``` 573*912701f9SAndroid Build Coastguard Worker> {{}} 574*912701f9SAndroid Build Coastguard Worker> ``` 575*912701f9SAndroid Build Coastguard Worker 576*912701f9SAndroid Build Coastguard Worker#### Text 577*912701f9SAndroid Build Coastguard Worker 578*912701f9SAndroid Build Coastguard Worker**_<dfn>text</dfn>_** is the translateable content of a _pattern_. 579*912701f9SAndroid Build Coastguard WorkerAny Unicode code point is allowed, except for U+0000 NULL 580*912701f9SAndroid Build Coastguard Workerand the surrogate code points U+D800 through U+DFFF inclusive. 581*912701f9SAndroid Build Coastguard WorkerThe characters U+005C REVERSE SOLIDUS `\`, 582*912701f9SAndroid Build Coastguard WorkerU+007B LEFT CURLY BRACKET `{`, and U+007D RIGHT CURLY BRACKET `}` 583*912701f9SAndroid Build Coastguard WorkerMUST be escaped as `\\`, `\{`, and `\}` respectively. 584*912701f9SAndroid Build Coastguard Worker 585*912701f9SAndroid Build Coastguard WorkerIn the ABNF, _text_ is represented by non-empty sequences of 586*912701f9SAndroid Build Coastguard Worker`simple-start-char`, `text-char`, and `text-escape`. 587*912701f9SAndroid Build Coastguard WorkerThe first of these is used at the start of a _simple message_, 588*912701f9SAndroid Build Coastguard Workerand matches `text-char` except for not allowing U+002E FULL STOP `.`. 589*912701f9SAndroid Build Coastguard WorkerThe ABNF uses `content-char` as a shared base for _text_ and _quoted literal_ characters. 590*912701f9SAndroid Build Coastguard Worker 591*912701f9SAndroid Build Coastguard WorkerWhitespace in _text_, including tabs, spaces, and newlines is significant and MUST 592*912701f9SAndroid Build Coastguard Workerbe preserved during formatting. 593*912701f9SAndroid Build Coastguard Worker 594*912701f9SAndroid Build Coastguard Worker```abnf 595*912701f9SAndroid Build Coastguard Workersimple-start-char = content-char / s / "@" / "|" 596*912701f9SAndroid Build Coastguard Workertext-char = content-char / s / "." / "@" / "|" 597*912701f9SAndroid Build Coastguard Workerquoted-char = content-char / s / "." / "@" / "{" / "}" 598*912701f9SAndroid Build Coastguard Workerreserved-char = content-char / "." 599*912701f9SAndroid Build Coastguard Workercontent-char = %x01-08 ; omit NULL (%x00), HTAB (%x09) and LF (%x0A) 600*912701f9SAndroid Build Coastguard Worker / %x0B-0C ; omit CR (%x0D) 601*912701f9SAndroid Build Coastguard Worker / %x0E-1F ; omit SP (%x20) 602*912701f9SAndroid Build Coastguard Worker / %x21-2D ; omit . (%x2E) 603*912701f9SAndroid Build Coastguard Worker / %x2F-3F ; omit @ (%x40) 604*912701f9SAndroid Build Coastguard Worker / %x41-5B ; omit \ (%x5C) 605*912701f9SAndroid Build Coastguard Worker / %x5D-7A ; omit { | } (%x7B-7D) 606*912701f9SAndroid Build Coastguard Worker / %x7E-2FFF ; omit IDEOGRAPHIC SPACE (%x3000) 607*912701f9SAndroid Build Coastguard Worker / %x3001-D7FF ; omit surrogates 608*912701f9SAndroid Build Coastguard Worker / %xE000-10FFFF 609*912701f9SAndroid Build Coastguard Worker``` 610*912701f9SAndroid Build Coastguard Worker 611*912701f9SAndroid Build Coastguard WorkerWhen a _pattern_ is quoted by embedding the _pattern_ in curly brackets, the 612*912701f9SAndroid Build Coastguard Workerresulting _message_ can be embedded into 613*912701f9SAndroid Build Coastguard Workervarious formats regardless of the container's whitespace trimming rules. 614*912701f9SAndroid Build Coastguard WorkerOtherwise, care must be taken to ensure that pattern-significant whitespace is preserved. 615*912701f9SAndroid Build Coastguard Worker 616*912701f9SAndroid Build Coastguard Worker> **Example** 617*912701f9SAndroid Build Coastguard Worker> In a Java `.properties` file, the values `hello` and `hello2` both contain 618*912701f9SAndroid Build Coastguard Worker> an identical _message_ which consists of a single _pattern_. 619*912701f9SAndroid Build Coastguard Worker> This _pattern_ consists of _text_ with exactly three spaces before and after the word "Hello": 620*912701f9SAndroid Build Coastguard Worker> 621*912701f9SAndroid Build Coastguard Worker> ```properties 622*912701f9SAndroid Build Coastguard Worker> hello = {{ Hello }} 623*912701f9SAndroid Build Coastguard Worker> hello2=\ Hello \ 624*912701f9SAndroid Build Coastguard Worker> ``` 625*912701f9SAndroid Build Coastguard Worker 626*912701f9SAndroid Build Coastguard Worker#### Placeholder 627*912701f9SAndroid Build Coastguard Worker 628*912701f9SAndroid Build Coastguard WorkerA **_<dfn>placeholder</dfn>_** is an _expression_ or _markup_ that appears inside of a _pattern_ 629*912701f9SAndroid Build Coastguard Workerand which will be replaced during the formatting of a _message_. 630*912701f9SAndroid Build Coastguard Worker 631*912701f9SAndroid Build Coastguard Worker```abnf 632*912701f9SAndroid Build Coastguard Workerplaceholder = expression / markup 633*912701f9SAndroid Build Coastguard Worker``` 634*912701f9SAndroid Build Coastguard Worker 635*912701f9SAndroid Build Coastguard Worker### Matcher 636*912701f9SAndroid Build Coastguard Worker 637*912701f9SAndroid Build Coastguard WorkerA **_<dfn>matcher</dfn>_** is the _complex body_ of a _message_ that allows runtime selection 638*912701f9SAndroid Build Coastguard Workerof the _pattern_ to use for formatting. 639*912701f9SAndroid Build Coastguard WorkerThis allows the form or content of a _message_ to vary based on values 640*912701f9SAndroid Build Coastguard Workerdetermined at runtime. 641*912701f9SAndroid Build Coastguard Worker 642*912701f9SAndroid Build Coastguard WorkerA _matcher_ consists of the keyword `.match` followed by at least one _selector_ 643*912701f9SAndroid Build Coastguard Workerand at least one _variant_. 644*912701f9SAndroid Build Coastguard Worker 645*912701f9SAndroid Build Coastguard WorkerWhen the _matcher_ is processed, the result will be a single _pattern_ that serves 646*912701f9SAndroid Build Coastguard Workeras the template for the formatting process. 647*912701f9SAndroid Build Coastguard Worker 648*912701f9SAndroid Build Coastguard WorkerA _message_ can only be considered _valid_ if the following requirements are 649*912701f9SAndroid Build Coastguard Workersatisfied: 650*912701f9SAndroid Build Coastguard Worker 651*912701f9SAndroid Build Coastguard Worker- The number of _keys_ on each _variant_ MUST be equal to the number of _selectors_. 652*912701f9SAndroid Build Coastguard Worker- At least one _variant_ MUST exist whose _keys_ are all equal to the "catch-all" key `*`. 653*912701f9SAndroid Build Coastguard Worker- Each _selector_ MUST have an _annotation_, 654*912701f9SAndroid Build Coastguard Worker or contain a _variable_ that directly or indirectly references a _declaration_ with an _annotation_. 655*912701f9SAndroid Build Coastguard Worker 656*912701f9SAndroid Build Coastguard Worker```abnf 657*912701f9SAndroid Build Coastguard Workermatcher = match-statement 1*([s] variant) 658*912701f9SAndroid Build Coastguard Workermatch-statement = match 1*([s] selector) 659*912701f9SAndroid Build Coastguard Worker``` 660*912701f9SAndroid Build Coastguard Worker 661*912701f9SAndroid Build Coastguard Worker> A _message_ with a _matcher_: 662*912701f9SAndroid Build Coastguard Worker> 663*912701f9SAndroid Build Coastguard Worker> ``` 664*912701f9SAndroid Build Coastguard Worker> .input {$count :number} 665*912701f9SAndroid Build Coastguard Worker> .match {$count} 666*912701f9SAndroid Build Coastguard Worker> one {{You have {$count} notification.}} 667*912701f9SAndroid Build Coastguard Worker> * {{You have {$count} notifications.}} 668*912701f9SAndroid Build Coastguard Worker> ``` 669*912701f9SAndroid Build Coastguard Worker 670*912701f9SAndroid Build Coastguard Worker> A _message_ containing a _matcher_ formatted on a single line: 671*912701f9SAndroid Build Coastguard Worker> 672*912701f9SAndroid Build Coastguard Worker> ``` 673*912701f9SAndroid Build Coastguard Worker> .match {:platform} windows {{Settings}} * {{Preferences}} 674*912701f9SAndroid Build Coastguard Worker> ``` 675*912701f9SAndroid Build Coastguard Worker 676*912701f9SAndroid Build Coastguard Worker#### Selector 677*912701f9SAndroid Build Coastguard Worker 678*912701f9SAndroid Build Coastguard WorkerA **_<dfn>selector</dfn>_** is an _expression_ that ranks or excludes the 679*912701f9SAndroid Build Coastguard Worker_variants_ based on the value of the corresponding _key_ in each _variant_. 680*912701f9SAndroid Build Coastguard WorkerThe combination of _selectors_ in a _matcher_ thus determines 681*912701f9SAndroid Build Coastguard Workerwhich _pattern_ will be used during formatting. 682*912701f9SAndroid Build Coastguard Worker 683*912701f9SAndroid Build Coastguard Worker```abnf 684*912701f9SAndroid Build Coastguard Workerselector = expression 685*912701f9SAndroid Build Coastguard Worker``` 686*912701f9SAndroid Build Coastguard Worker 687*912701f9SAndroid Build Coastguard WorkerThere MUST be at least one _selector_ in a _matcher_. 688*912701f9SAndroid Build Coastguard WorkerThere MAY be any number of additional _selectors_. 689*912701f9SAndroid Build Coastguard Worker 690*912701f9SAndroid Build Coastguard Worker> A _message_ with a single _selector_ that uses a custom _function_ 691*912701f9SAndroid Build Coastguard Worker> `:hasCase` which is a _selector_ that allows the _message_ to choose a _pattern_ 692*912701f9SAndroid Build Coastguard Worker> based on grammatical case: 693*912701f9SAndroid Build Coastguard Worker> 694*912701f9SAndroid Build Coastguard Worker> ``` 695*912701f9SAndroid Build Coastguard Worker> .match {$userName :hasCase} 696*912701f9SAndroid Build Coastguard Worker> vocative {{Hello, {$userName :person case=vocative}!}} 697*912701f9SAndroid Build Coastguard Worker> accusative {{Please welcome {$userName :person case=accusative}!}} 698*912701f9SAndroid Build Coastguard Worker> * {{Hello!}} 699*912701f9SAndroid Build Coastguard Worker> ``` 700*912701f9SAndroid Build Coastguard Worker 701*912701f9SAndroid Build Coastguard Worker> A message with two _selectors_: 702*912701f9SAndroid Build Coastguard Worker> 703*912701f9SAndroid Build Coastguard Worker> ``` 704*912701f9SAndroid Build Coastguard Worker> .input {$numLikes :integer} 705*912701f9SAndroid Build Coastguard Worker> .input {$numShares :integer} 706*912701f9SAndroid Build Coastguard Worker> .match {$numLikes} {$numShares} 707*912701f9SAndroid Build Coastguard Worker> 0 0 {{Your item has no likes and has not been shared.}} 708*912701f9SAndroid Build Coastguard Worker> 0 one {{Your item has no likes and has been shared {$numShares} time.}} 709*912701f9SAndroid Build Coastguard Worker> 0 * {{Your item has no likes and has been shared {$numShares} times.}} 710*912701f9SAndroid Build Coastguard Worker> one 0 {{Your item has {$numLikes} like and has not been shared.}} 711*912701f9SAndroid Build Coastguard Worker> one one {{Your item has {$numLikes} like and has been shared {$numShares} time.}} 712*912701f9SAndroid Build Coastguard Worker> one * {{Your item has {$numLikes} like and has been shared {$numShares} times.}} 713*912701f9SAndroid Build Coastguard Worker> * 0 {{Your item has {$numLikes} likes and has not been shared.}} 714*912701f9SAndroid Build Coastguard Worker> * one {{Your item has {$numLikes} likes and has been shared {$numShares} time.}} 715*912701f9SAndroid Build Coastguard Worker> * * {{Your item has {$numLikes} likes and has been shared {$numShares} times.}} 716*912701f9SAndroid Build Coastguard Worker> ``` 717*912701f9SAndroid Build Coastguard Worker 718*912701f9SAndroid Build Coastguard Worker#### Variant 719*912701f9SAndroid Build Coastguard Worker 720*912701f9SAndroid Build Coastguard WorkerA **_<dfn>variant</dfn>_** is a _quoted pattern_ associated with a set of _keys_ in a _matcher_. 721*912701f9SAndroid Build Coastguard WorkerEach _variant_ MUST begin with a sequence of _keys_, 722*912701f9SAndroid Build Coastguard Workerand terminate with a valid _quoted pattern_. 723*912701f9SAndroid Build Coastguard WorkerThe number of _keys_ in each _variant_ MUST match the number of _selectors_ in the _matcher_. 724*912701f9SAndroid Build Coastguard Worker 725*912701f9SAndroid Build Coastguard WorkerEach _key_ is separated from each other by whitespace. 726*912701f9SAndroid Build Coastguard WorkerWhitespace is permitted but not required between the last _key_ and the _quoted pattern_. 727*912701f9SAndroid Build Coastguard Worker 728*912701f9SAndroid Build Coastguard Worker```abnf 729*912701f9SAndroid Build Coastguard Workervariant = key *(s key) [s] quoted-pattern 730*912701f9SAndroid Build Coastguard Workerkey = literal / "*" 731*912701f9SAndroid Build Coastguard Worker``` 732*912701f9SAndroid Build Coastguard Worker 733*912701f9SAndroid Build Coastguard Worker##### Key 734*912701f9SAndroid Build Coastguard Worker 735*912701f9SAndroid Build Coastguard WorkerA **_<dfn>key</dfn>_** is a value in a _variant_ for use by a _selector_ when ranking 736*912701f9SAndroid Build Coastguard Workeror excluding _variants_ during the _matcher_ process. 737*912701f9SAndroid Build Coastguard WorkerA _key_ can be either a _literal_ value or the "catch-all" key `*`. 738*912701f9SAndroid Build Coastguard Worker 739*912701f9SAndroid Build Coastguard WorkerThe **_<dfn>catch-all key</dfn>_** is a special key, represented by `*`, 740*912701f9SAndroid Build Coastguard Workerthat matches all values for a given _selector_. 741*912701f9SAndroid Build Coastguard Worker 742*912701f9SAndroid Build Coastguard Worker### Expressions 743*912701f9SAndroid Build Coastguard Worker 744*912701f9SAndroid Build Coastguard WorkerAn **_<dfn>expression</dfn>_** is a part of a _message_ that will be determined 745*912701f9SAndroid Build Coastguard Workerduring the _message_'s formatting. 746*912701f9SAndroid Build Coastguard Worker 747*912701f9SAndroid Build Coastguard WorkerAn _expression_ MUST begin with U+007B LEFT CURLY BRACKET `{` 748*912701f9SAndroid Build Coastguard Workerand end with U+007D RIGHT CURLY BRACKET `}`. 749*912701f9SAndroid Build Coastguard WorkerAn _expression_ MUST NOT be empty. 750*912701f9SAndroid Build Coastguard WorkerAn _expression_ cannot contain another _expression_. 751*912701f9SAndroid Build Coastguard WorkerAn _expression_ MAY contain one more _attributes_. 752*912701f9SAndroid Build Coastguard Worker 753*912701f9SAndroid Build Coastguard WorkerA **_<dfn>literal-expression</dfn>_** contains a _literal_, 754*912701f9SAndroid Build Coastguard Workeroptionally followed by an _annotation_. 755*912701f9SAndroid Build Coastguard Worker 756*912701f9SAndroid Build Coastguard WorkerA **_<dfn>variable-expression</dfn>_** contains a _variable_, 757*912701f9SAndroid Build Coastguard Workeroptionally followed by an _annotation_. 758*912701f9SAndroid Build Coastguard Worker 759*912701f9SAndroid Build Coastguard WorkerAn **_<dfn>annotation-expression</dfn>_** contains an _annotation_ without an _operand_. 760*912701f9SAndroid Build Coastguard Worker 761*912701f9SAndroid Build Coastguard Worker```abnf 762*912701f9SAndroid Build Coastguard Workerexpression = literal-expression 763*912701f9SAndroid Build Coastguard Worker / variable-expression 764*912701f9SAndroid Build Coastguard Worker / annotation-expression 765*912701f9SAndroid Build Coastguard Workerliteral-expression = "{" [s] literal [s annotation] *(s attribute) [s] "}" 766*912701f9SAndroid Build Coastguard Workervariable-expression = "{" [s] variable [s annotation] *(s attribute) [s] "}" 767*912701f9SAndroid Build Coastguard Workerannotation-expression = "{" [s] annotation *(s attribute) [s] "}" 768*912701f9SAndroid Build Coastguard Worker``` 769*912701f9SAndroid Build Coastguard Worker 770*912701f9SAndroid Build Coastguard WorkerThere are several types of _expression_ that can appear in a _message_. 771*912701f9SAndroid Build Coastguard WorkerAll _expressions_ share a common syntax. The types of _expression_ are: 772*912701f9SAndroid Build Coastguard Worker 773*912701f9SAndroid Build Coastguard Worker1. The value of a _local-declaration_ 774*912701f9SAndroid Build Coastguard Worker2. A _selector_ 775*912701f9SAndroid Build Coastguard Worker3. A kind of _placeholder_ in a _pattern_ 776*912701f9SAndroid Build Coastguard Worker 777*912701f9SAndroid Build Coastguard WorkerAdditionally, an _input-declaration_ can contain a _variable-expression_. 778*912701f9SAndroid Build Coastguard Worker 779*912701f9SAndroid Build Coastguard Worker> Examples of different types of _expression_ 780*912701f9SAndroid Build Coastguard Worker> 781*912701f9SAndroid Build Coastguard Worker> Declarations: 782*912701f9SAndroid Build Coastguard Worker> 783*912701f9SAndroid Build Coastguard Worker> ``` 784*912701f9SAndroid Build Coastguard Worker> .input {$x :function option=value} 785*912701f9SAndroid Build Coastguard Worker> .local $y = {|This is an expression|} 786*912701f9SAndroid Build Coastguard Worker> ``` 787*912701f9SAndroid Build Coastguard Worker> 788*912701f9SAndroid Build Coastguard Worker> Selectors: 789*912701f9SAndroid Build Coastguard Worker> 790*912701f9SAndroid Build Coastguard Worker> ``` 791*912701f9SAndroid Build Coastguard Worker> .match {$selector :functionRequired} 792*912701f9SAndroid Build Coastguard Worker> ``` 793*912701f9SAndroid Build Coastguard Worker> 794*912701f9SAndroid Build Coastguard Worker> Placeholders: 795*912701f9SAndroid Build Coastguard Worker> 796*912701f9SAndroid Build Coastguard Worker> ``` 797*912701f9SAndroid Build Coastguard Worker> This placeholder contains a literal expression: {|literal|} 798*912701f9SAndroid Build Coastguard Worker> This placeholder contains a variable expression: {$variable} 799*912701f9SAndroid Build Coastguard Worker> This placeholder references a function on a variable: {$variable :function with=options} 800*912701f9SAndroid Build Coastguard Worker> This placeholder contains a function expression with a variable-valued option: {:function option=$variable} 801*912701f9SAndroid Build Coastguard Worker> ``` 802*912701f9SAndroid Build Coastguard Worker 803*912701f9SAndroid Build Coastguard Worker#### Annotation 804*912701f9SAndroid Build Coastguard Worker 805*912701f9SAndroid Build Coastguard WorkerAn **_<dfn>annotation</dfn>_** is part of an _expression_ containing either 806*912701f9SAndroid Build Coastguard Workera _function_ together with its associated _options_, or 807*912701f9SAndroid Build Coastguard Workera _private-use annotation_ or a _reserved annotation_. 808*912701f9SAndroid Build Coastguard Worker 809*912701f9SAndroid Build Coastguard Worker```abnf 810*912701f9SAndroid Build Coastguard Workerannotation = function 811*912701f9SAndroid Build Coastguard Worker / private-use-annotation 812*912701f9SAndroid Build Coastguard Worker / reserved-annotation 813*912701f9SAndroid Build Coastguard Worker``` 814*912701f9SAndroid Build Coastguard Worker 815*912701f9SAndroid Build Coastguard WorkerAn **_<dfn>operand</dfn>_** is the _literal_ of a _literal-expression_ or 816*912701f9SAndroid Build Coastguard Workerthe _variable_ of a _variable-expression_. 817*912701f9SAndroid Build Coastguard Worker 818*912701f9SAndroid Build Coastguard WorkerAn _annotation_ can appear in an _expression_ by itself or following a single _operand_. 819*912701f9SAndroid Build Coastguard WorkerWhen following an _operand_, the _operand_ serves as input to the _annotation_. 820*912701f9SAndroid Build Coastguard Worker 821*912701f9SAndroid Build Coastguard Worker##### Function 822*912701f9SAndroid Build Coastguard Worker 823*912701f9SAndroid Build Coastguard WorkerA **_<dfn>function</dfn>_** is named functionality in an _annotation_. 824*912701f9SAndroid Build Coastguard Worker_Functions_ are used to evaluate, format, select, or otherwise process data 825*912701f9SAndroid Build Coastguard Workervalues during formatting. 826*912701f9SAndroid Build Coastguard Worker 827*912701f9SAndroid Build Coastguard WorkerEach _function_ is defined by the runtime's _function registry_. 828*912701f9SAndroid Build Coastguard WorkerA _function_'s entry in the _function registry_ will define 829*912701f9SAndroid Build Coastguard Workerwhether the _function_ is a _selector_ or formatter (or both), 830*912701f9SAndroid Build Coastguard Workerwhether an _operand_ is required, 831*912701f9SAndroid Build Coastguard Workerwhat form the values of an _operand_ can take, 832*912701f9SAndroid Build Coastguard Workerwhat _options_ and _option_ values are valid, 833*912701f9SAndroid Build Coastguard Workerand what outputs might result. 834*912701f9SAndroid Build Coastguard WorkerSee [function registry](#function-registry) for more information. 835*912701f9SAndroid Build Coastguard Worker 836*912701f9SAndroid Build Coastguard WorkerA _function_ starts with a prefix sigil `:` followed by an _identifier_. 837*912701f9SAndroid Build Coastguard WorkerThe _identifier_ MAY be followed by one or more _options_. 838*912701f9SAndroid Build Coastguard Worker_Options_ are not required. 839*912701f9SAndroid Build Coastguard Worker 840*912701f9SAndroid Build Coastguard Worker```abnf 841*912701f9SAndroid Build Coastguard Workerfunction = ":" identifier *(s option) 842*912701f9SAndroid Build Coastguard Worker``` 843*912701f9SAndroid Build Coastguard Worker 844*912701f9SAndroid Build Coastguard Worker> A _message_ with a _function_ operating on the _variable_ `$now`: 845*912701f9SAndroid Build Coastguard Worker> 846*912701f9SAndroid Build Coastguard Worker> ``` 847*912701f9SAndroid Build Coastguard Worker> It is now {$now :datetime}. 848*912701f9SAndroid Build Coastguard Worker> ``` 849*912701f9SAndroid Build Coastguard Worker 850*912701f9SAndroid Build Coastguard Worker###### Options 851*912701f9SAndroid Build Coastguard Worker 852*912701f9SAndroid Build Coastguard WorkerAn **_<dfn>option</dfn>_** is a key-value pair 853*912701f9SAndroid Build Coastguard Workercontaining a named argument that is passed to a _function_. 854*912701f9SAndroid Build Coastguard Worker 855*912701f9SAndroid Build Coastguard WorkerAn _option_ has an _identifier_ and a _value_. 856*912701f9SAndroid Build Coastguard WorkerThe _identifier_ is separated from the _value_ by an U+003D EQUALS SIGN `=` along with 857*912701f9SAndroid Build Coastguard Workeroptional whitespace. 858*912701f9SAndroid Build Coastguard WorkerThe value of an _option_ can be either a _literal_ or a _variable_. 859*912701f9SAndroid Build Coastguard Worker 860*912701f9SAndroid Build Coastguard WorkerMultiple _options_ are permitted in an _annotation_. 861*912701f9SAndroid Build Coastguard Worker_Options_ are separated from the preceding _function_ _identifier_ 862*912701f9SAndroid Build Coastguard Workerand from each other by whitespace. 863*912701f9SAndroid Build Coastguard WorkerEach _option_'s _identifier_ MUST be unique within the _annotation_: 864*912701f9SAndroid Build Coastguard Workeran _annotation_ with duplicate _option_ _identifiers_ is not valid. 865*912701f9SAndroid Build Coastguard Worker 866*912701f9SAndroid Build Coastguard WorkerThe order of _options_ is not significant. 867*912701f9SAndroid Build Coastguard Worker 868*912701f9SAndroid Build Coastguard Worker```abnf 869*912701f9SAndroid Build Coastguard Workeroption = identifier [s] "=" [s] (literal / variable) 870*912701f9SAndroid Build Coastguard Worker``` 871*912701f9SAndroid Build Coastguard Worker 872*912701f9SAndroid Build Coastguard Worker> Examples of _functions_ with _options_ 873*912701f9SAndroid Build Coastguard Worker> 874*912701f9SAndroid Build Coastguard Worker> A _message_ using the `:datetime` function. 875*912701f9SAndroid Build Coastguard Worker> The _option_ `weekday` has the literal `long` as its value: 876*912701f9SAndroid Build Coastguard Worker> 877*912701f9SAndroid Build Coastguard Worker> ``` 878*912701f9SAndroid Build Coastguard Worker> Today is {$date :datetime weekday=long}! 879*912701f9SAndroid Build Coastguard Worker> ``` 880*912701f9SAndroid Build Coastguard Worker 881*912701f9SAndroid Build Coastguard Worker> A _message_ using the `:datetime` function. 882*912701f9SAndroid Build Coastguard Worker> The _option_ `weekday` has a variable `$dateStyle` as its value: 883*912701f9SAndroid Build Coastguard Worker> 884*912701f9SAndroid Build Coastguard Worker> ``` 885*912701f9SAndroid Build Coastguard Worker> Today is {$date :datetime weekday=$dateStyle}! 886*912701f9SAndroid Build Coastguard Worker> ``` 887*912701f9SAndroid Build Coastguard Worker 888*912701f9SAndroid Build Coastguard Worker##### Private-Use Annotations 889*912701f9SAndroid Build Coastguard Worker 890*912701f9SAndroid Build Coastguard WorkerA **_<dfn>private-use annotation</dfn>_** is an _annotation_ whose syntax is reserved 891*912701f9SAndroid Build Coastguard Workerfor use by a specific implementation or by private agreement between multiple implementations. 892*912701f9SAndroid Build Coastguard WorkerImplementations MAY define their own meaning and semantics for _private-use annotations_. 893*912701f9SAndroid Build Coastguard Worker 894*912701f9SAndroid Build Coastguard WorkerA _private-use annotation_ starts with either U+0026 AMPERSAND `&` or U+005E CIRCUMFLEX ACCENT `^`. 895*912701f9SAndroid Build Coastguard Worker 896*912701f9SAndroid Build Coastguard WorkerCharacters, including whitespace, are assigned meaning by the implementation. 897*912701f9SAndroid Build Coastguard WorkerThe definition of escapes in the `reserved-body` production, used for the body of 898*912701f9SAndroid Build Coastguard Workera _private-use annotation_ is an affordance to implementations that 899*912701f9SAndroid Build Coastguard Workerwish to use a syntax exactly like other functions. Specifically: 900*912701f9SAndroid Build Coastguard Worker 901*912701f9SAndroid Build Coastguard Worker- The characters `\`, `{`, and `}` MUST be escaped as `\\`, `\{`, and `\}` respectively 902*912701f9SAndroid Build Coastguard Worker when they appear in the body of a _private-use annotation_. 903*912701f9SAndroid Build Coastguard Worker- The character `|` is special: it SHOULD be escaped as `\|` in a _private-use annotation_, 904*912701f9SAndroid Build Coastguard Worker but can appear unescaped as long as it is paired with another `|`. 905*912701f9SAndroid Build Coastguard Worker This is an affordance to allow _literals_ to appear in the private use syntax. 906*912701f9SAndroid Build Coastguard Worker 907*912701f9SAndroid Build Coastguard WorkerA _private-use annotation_ MAY be empty after its introducing sigil. 908*912701f9SAndroid Build Coastguard Worker 909*912701f9SAndroid Build Coastguard Worker```abnf 910*912701f9SAndroid Build Coastguard Workerprivate-use-annotation = private-start [[s] reserved-body] 911*912701f9SAndroid Build Coastguard Workerprivate-start = "^" / "&" 912*912701f9SAndroid Build Coastguard Worker``` 913*912701f9SAndroid Build Coastguard Worker 914*912701f9SAndroid Build Coastguard Worker> [!NOTE] 915*912701f9SAndroid Build Coastguard Worker> Users are cautioned that _private-use annotations_ cannot be reliably exchanged 916*912701f9SAndroid Build Coastguard Worker> and can result in errors during formatting. 917*912701f9SAndroid Build Coastguard Worker> It is generally a better idea to use the function registry 918*912701f9SAndroid Build Coastguard Worker> to define additional formatting or annotation options. 919*912701f9SAndroid Build Coastguard Worker 920*912701f9SAndroid Build Coastguard Worker> Here are some examples of what _private-use_ sequences might look like: 921*912701f9SAndroid Build Coastguard Worker> 922*912701f9SAndroid Build Coastguard Worker> ``` 923*912701f9SAndroid Build Coastguard Worker> Here's private use with an operand: {$foo &bar} 924*912701f9SAndroid Build Coastguard Worker> Here's a placeholder that is entirely private-use: {&anything here} 925*912701f9SAndroid Build Coastguard Worker> Here's a private-use function that uses normal function syntax: {$operand ^foo option=|literal|} 926*912701f9SAndroid Build Coastguard Worker> The character \| has to be paired or escaped: {&private || |something between| or isolated: \| } 927*912701f9SAndroid Build Coastguard Worker> Stop {& "translate 'stop' as a verb" might be a translator instruction or comment } 928*912701f9SAndroid Build Coastguard Worker> Protect stuff in {^ph}<a>{^/ph}private use{^ph}</a>{^/ph} 929*912701f9SAndroid Build Coastguard Worker> ``` 930*912701f9SAndroid Build Coastguard Worker 931*912701f9SAndroid Build Coastguard Worker##### Reserved Annotations 932*912701f9SAndroid Build Coastguard Worker 933*912701f9SAndroid Build Coastguard WorkerA **_<dfn>reserved annotation</dfn>_** is an _annotation_ whose syntax is reserved 934*912701f9SAndroid Build Coastguard Workerfor future standardization. 935*912701f9SAndroid Build Coastguard Worker 936*912701f9SAndroid Build Coastguard WorkerA _reserved annotation_ starts with a reserved character. 937*912701f9SAndroid Build Coastguard WorkerThe remaining part of a _reserved annotation_, called a _reserved body_, 938*912701f9SAndroid Build Coastguard WorkerMAY be empty or contain arbitrary text that starts and ends with 939*912701f9SAndroid Build Coastguard Workera non-whitespace character. 940*912701f9SAndroid Build Coastguard Worker 941*912701f9SAndroid Build Coastguard WorkerThis allows maximum flexibility in future standardization, 942*912701f9SAndroid Build Coastguard Workeras future definitions MAY define additional semantics and constraints 943*912701f9SAndroid Build Coastguard Workeron the contents of these _annotations_. 944*912701f9SAndroid Build Coastguard Worker 945*912701f9SAndroid Build Coastguard WorkerImplementations MUST NOT assign meaning or semantics to 946*912701f9SAndroid Build Coastguard Workeran _annotation_ starting with `reserved-annotation-start`: 947*912701f9SAndroid Build Coastguard Workerthese are reserved for future standardization. 948*912701f9SAndroid Build Coastguard WorkerWhitespace before or after a _reserved body_ is not part of the _reserved body_. 949*912701f9SAndroid Build Coastguard WorkerImplementations MUST NOT remove or alter the contents of a _reserved body_, 950*912701f9SAndroid Build Coastguard Workerincluding any interior whitespace, 951*912701f9SAndroid Build Coastguard Workerbut MAY remove or alter whitespace before or after the _reserved body_. 952*912701f9SAndroid Build Coastguard Worker 953*912701f9SAndroid Build Coastguard WorkerWhile a reserved sequence is technically "well-formed", 954*912701f9SAndroid Build Coastguard Workerunrecognized _reserved-annotations_ or _private-use-annotations_ have no meaning. 955*912701f9SAndroid Build Coastguard Worker 956*912701f9SAndroid Build Coastguard Worker```abnf 957*912701f9SAndroid Build Coastguard Workerreserved-annotation = reserved-annotation-start [[s] reserved-body] 958*912701f9SAndroid Build Coastguard Workerreserved-annotation-start = "!" / "%" / "*" / "+" / "<" / ">" / "?" / "~" 959*912701f9SAndroid Build Coastguard Worker 960*912701f9SAndroid Build Coastguard Workerreserved-body = reserved-body-part *([s] reserved-body-part) 961*912701f9SAndroid Build Coastguard Workerreserved-body-part = reserved-char / reserved-escape / quoted 962*912701f9SAndroid Build Coastguard Worker``` 963*912701f9SAndroid Build Coastguard Worker 964*912701f9SAndroid Build Coastguard Worker### Markup 965*912701f9SAndroid Build Coastguard Worker 966*912701f9SAndroid Build Coastguard Worker**_<dfn>Markup</dfn>_** _placeholders_ are _pattern_ parts 967*912701f9SAndroid Build Coastguard Workerthat can be used to represent non-language parts of a _message_, 968*912701f9SAndroid Build Coastguard Workersuch as inline elements or styling that should apply to a span of parts. 969*912701f9SAndroid Build Coastguard Worker 970*912701f9SAndroid Build Coastguard Worker_Markup_ MUST begin with U+007B LEFT CURLY BRACKET `{` 971*912701f9SAndroid Build Coastguard Workerand end with U+007D RIGHT CURLY BRACKET `}`. 972*912701f9SAndroid Build Coastguard Worker_Markup_ MAY contain one more _attributes_. 973*912701f9SAndroid Build Coastguard Worker 974*912701f9SAndroid Build Coastguard Worker_Markup_ comes in three forms: 975*912701f9SAndroid Build Coastguard Worker 976*912701f9SAndroid Build Coastguard Worker**_<dfn>Markup-open</dfn>_** starts with U+0023 NUMBER SIGN `#` and 977*912701f9SAndroid Build Coastguard Workerrepresents an opening element within the _message_, 978*912701f9SAndroid Build Coastguard Workersuch as markup used to start a span. 979*912701f9SAndroid Build Coastguard WorkerIt MAY include _options_. 980*912701f9SAndroid Build Coastguard Worker 981*912701f9SAndroid Build Coastguard Worker**_<dfn>Markup-standalone</dfn>_** starts with U+0023 NUMBER SIGN `#` 982*912701f9SAndroid Build Coastguard Workerand has a U+002F SOLIDUS `/` immediately before its closing `}` 983*912701f9SAndroid Build Coastguard Workerrepresenting a self-closing or standalone element within the _message_. 984*912701f9SAndroid Build Coastguard WorkerIt MAY include _options_. 985*912701f9SAndroid Build Coastguard Worker 986*912701f9SAndroid Build Coastguard Worker**_<dfn>Markup-close</dfn>_** starts with U+002F SOLIDUS `/` and 987*912701f9SAndroid Build Coastguard Workeris a _pattern_ part ending a span. 988*912701f9SAndroid Build Coastguard Worker 989*912701f9SAndroid Build Coastguard Worker```abnf 990*912701f9SAndroid Build Coastguard Workermarkup = "{" [s] "#" identifier *(s option) *(s attribute) [s] ["/"] "}" ; open and standalone 991*912701f9SAndroid Build Coastguard Worker / "{" [s] "/" identifier *(s option) *(s attribute) [s] "}" ; close 992*912701f9SAndroid Build Coastguard Worker``` 993*912701f9SAndroid Build Coastguard Worker 994*912701f9SAndroid Build Coastguard Worker> A _message_ with one `button` markup span and a standalone `img` markup element: 995*912701f9SAndroid Build Coastguard Worker> 996*912701f9SAndroid Build Coastguard Worker> ``` 997*912701f9SAndroid Build Coastguard Worker> {#button}Submit{/button} or {#img alt=|Cancel| /}. 998*912701f9SAndroid Build Coastguard Worker> ``` 999*912701f9SAndroid Build Coastguard Worker 1000*912701f9SAndroid Build Coastguard Worker> A _message_ with attributes in the closing tag: 1001*912701f9SAndroid Build Coastguard Worker> 1002*912701f9SAndroid Build Coastguard Worker> ``` 1003*912701f9SAndroid Build Coastguard Worker> {#ansi attr=|bold,italic|}Bold and italic{/ansi attr=|bold|} italic only {/ansi attr=|italic|} no formatting.} 1004*912701f9SAndroid Build Coastguard Worker> ``` 1005*912701f9SAndroid Build Coastguard Worker 1006*912701f9SAndroid Build Coastguard WorkerA _markup-open_ can appear without a corresponding _markup-close_. 1007*912701f9SAndroid Build Coastguard WorkerA _markup-close_ can appear without a corresponding _markup-open_. 1008*912701f9SAndroid Build Coastguard Worker_Markup_ _placeholders_ can appear in any order without making the _message_ invalid. 1009*912701f9SAndroid Build Coastguard WorkerHowever, specifications or implementations defining _markup_ might impose requirements 1010*912701f9SAndroid Build Coastguard Workeron the pairing, ordering, or contents of _markup_ during _formatting_. 1011*912701f9SAndroid Build Coastguard Worker 1012*912701f9SAndroid Build Coastguard Worker### Attributes 1013*912701f9SAndroid Build Coastguard Worker 1014*912701f9SAndroid Build Coastguard Worker**_Attributes_ are reserved for standardization by future versions of this specification.** 1015*912701f9SAndroid Build Coastguard WorkerExamples in this section are meant to be illustrative and 1016*912701f9SAndroid Build Coastguard Workermight not match future requirements or usage. 1017*912701f9SAndroid Build Coastguard Worker 1018*912701f9SAndroid Build Coastguard Worker> [!NOTE] 1019*912701f9SAndroid Build Coastguard Worker> The Tech Preview does not provide a built-in mechanism for overriding 1020*912701f9SAndroid Build Coastguard Worker> values in the _formatting context_ (most notably the locale) 1021*912701f9SAndroid Build Coastguard Worker> Nor does it provide a mechanism for identifying specific expressions 1022*912701f9SAndroid Build Coastguard Worker> such as by assigning a name or id. 1023*912701f9SAndroid Build Coastguard Worker> The utility of these types of mechanisms has been debated. 1024*912701f9SAndroid Build Coastguard Worker> There are at least two proposed mechanisms for implementing support for 1025*912701f9SAndroid Build Coastguard Worker> these. 1026*912701f9SAndroid Build Coastguard Worker> Specifically, one mechanism would be to reserve specifically-named options, 1027*912701f9SAndroid Build Coastguard Worker> possibly using a Unicode namespace (i.e. `locale=xxx` or `u:locale=xxx`). 1028*912701f9SAndroid Build Coastguard Worker> Such options would be reserved for use in any and all functions or markup. 1029*912701f9SAndroid Build Coastguard Worker> The other mechanism would be to use the reserved "expression attribute" syntax 1030*912701f9SAndroid Build Coastguard Worker> for this purpose (i.e. `@locale=xxx` or `@id=foo`) 1031*912701f9SAndroid Build Coastguard Worker> Neither mechanism was included in this Tech Preview. 1032*912701f9SAndroid Build Coastguard Worker> Feedback on the preferred mechanism for managing these features 1033*912701f9SAndroid Build Coastguard Worker> is strongly desired. 1034*912701f9SAndroid Build Coastguard Worker> 1035*912701f9SAndroid Build Coastguard Worker> In the meantime, function authors and other implementers are cautioned to avoid creating 1036*912701f9SAndroid Build Coastguard Worker> function-specific or implementation-specific option values for this purpose. 1037*912701f9SAndroid Build Coastguard Worker> One workaround would be to use the implementation's namespace for these 1038*912701f9SAndroid Build Coastguard Worker> features to insure later interoperability when such a mechanism is finalized 1039*912701f9SAndroid Build Coastguard Worker> during the Tech Preview period. 1040*912701f9SAndroid Build Coastguard Worker> Specifically: 1041*912701f9SAndroid Build Coastguard Worker> - Avoid specifying an option for setting the locale of an expression as different from 1042*912701f9SAndroid Build Coastguard Worker> that of the overall _message_ locale, or use a namespace that later maps to the final 1043*912701f9SAndroid Build Coastguard Worker> mechanism. 1044*912701f9SAndroid Build Coastguard Worker> - Avoid specifying options for the purpose of linking placeholders 1045*912701f9SAndroid Build Coastguard Worker> (such as to pair opening markup to closing markup). 1046*912701f9SAndroid Build Coastguard Worker> If such an option is created, the implementer should use an 1047*912701f9SAndroid Build Coastguard Worker> implementation-specific namespace. 1048*912701f9SAndroid Build Coastguard Worker> Users and implementers are cautioned that such options might be 1049*912701f9SAndroid Build Coastguard Worker> replaced with a standard mechanism in a future version. 1050*912701f9SAndroid Build Coastguard Worker> - Avoid specifying generic options to communicate with translators and 1051*912701f9SAndroid Build Coastguard Worker> translation tooling (i.e. implementation-specific options that apply to all 1052*912701f9SAndroid Build Coastguard Worker> functions. 1053*912701f9SAndroid Build Coastguard Worker> The above are all desirable features. 1054*912701f9SAndroid Build Coastguard Worker> We welcome contributions to and proposals for such features during the 1055*912701f9SAndroid Build Coastguard Worker> Technical Preview. 1056*912701f9SAndroid Build Coastguard Worker 1057*912701f9SAndroid Build Coastguard WorkerAn **_<dfn>attribute</dfn>_** is an _identifier_ with an optional value 1058*912701f9SAndroid Build Coastguard Workerthat appears in an _expression_ or in _markup_. 1059*912701f9SAndroid Build Coastguard Worker 1060*912701f9SAndroid Build Coastguard Worker_Attributes_ are prefixed by a U+0040 COMMERCIAL AT `@` sign, 1061*912701f9SAndroid Build Coastguard Workerfollowed by an _identifier_. 1062*912701f9SAndroid Build Coastguard WorkerAn _attribute_ MAY have a _value_ which is separated from the _identifier_ 1063*912701f9SAndroid Build Coastguard Workerby an U+003D EQUALS SIGN `=` along with optional whitespace. 1064*912701f9SAndroid Build Coastguard WorkerThe _value_ of an _attribute_ can be either a _literal_ or a _variable_. 1065*912701f9SAndroid Build Coastguard Worker 1066*912701f9SAndroid Build Coastguard WorkerMultiple _attributes_ are permitted in an _expression_ or _markup_. 1067*912701f9SAndroid Build Coastguard WorkerEach _attribute_ is separated by whitespace. 1068*912701f9SAndroid Build Coastguard Worker 1069*912701f9SAndroid Build Coastguard WorkerThe order of _attributes_ is not significant. 1070*912701f9SAndroid Build Coastguard Worker 1071*912701f9SAndroid Build Coastguard Worker 1072*912701f9SAndroid Build Coastguard Worker```abnf 1073*912701f9SAndroid Build Coastguard Workerattribute = "@" identifier [[s] "=" [s] (literal / variable)] 1074*912701f9SAndroid Build Coastguard Worker``` 1075*912701f9SAndroid Build Coastguard Worker 1076*912701f9SAndroid Build Coastguard Worker> Examples of _expressions_ and _markup_ with _attributes_: 1077*912701f9SAndroid Build Coastguard Worker> 1078*912701f9SAndroid Build Coastguard Worker> A _message_ including a _literal_ that should not be translated: 1079*912701f9SAndroid Build Coastguard Worker> 1080*912701f9SAndroid Build Coastguard Worker> ``` 1081*912701f9SAndroid Build Coastguard Worker> In French, "{|bonjour| @translate=no}" is a greeting 1082*912701f9SAndroid Build Coastguard Worker> ``` 1083*912701f9SAndroid Build Coastguard Worker> 1084*912701f9SAndroid Build Coastguard Worker> A _message_ with _markup_ that should not be copied: 1085*912701f9SAndroid Build Coastguard Worker> 1086*912701f9SAndroid Build Coastguard Worker> ``` 1087*912701f9SAndroid Build Coastguard Worker> Have a {#span @can-copy}great and wonderful{/span @can-copy} birthday! 1088*912701f9SAndroid Build Coastguard Worker> ``` 1089*912701f9SAndroid Build Coastguard Worker 1090*912701f9SAndroid Build Coastguard Worker### Other Syntax Elements 1091*912701f9SAndroid Build Coastguard Worker 1092*912701f9SAndroid Build Coastguard WorkerThis section defines common elements used to construct _messages_. 1093*912701f9SAndroid Build Coastguard Worker 1094*912701f9SAndroid Build Coastguard Worker#### Keywords 1095*912701f9SAndroid Build Coastguard Worker 1096*912701f9SAndroid Build Coastguard WorkerA **_<dfn>keyword</dfn>_** is a reserved token that has a unique meaning in the _message_ syntax. 1097*912701f9SAndroid Build Coastguard Worker 1098*912701f9SAndroid Build Coastguard WorkerThe following three keywords are defined: `.input`, `.local`, and `.match`. 1099*912701f9SAndroid Build Coastguard WorkerKeywords are always lowercase and start with U+002E FULL STOP `.`. 1100*912701f9SAndroid Build Coastguard Worker 1101*912701f9SAndroid Build Coastguard Worker```abnf 1102*912701f9SAndroid Build Coastguard Workerinput = %s".input" 1103*912701f9SAndroid Build Coastguard Workerlocal = %s".local" 1104*912701f9SAndroid Build Coastguard Workermatch = %s".match" 1105*912701f9SAndroid Build Coastguard Worker``` 1106*912701f9SAndroid Build Coastguard Worker 1107*912701f9SAndroid Build Coastguard Worker#### Literals 1108*912701f9SAndroid Build Coastguard Worker 1109*912701f9SAndroid Build Coastguard WorkerA **_<dfn>literal</dfn>_** is a character sequence that appears outside 1110*912701f9SAndroid Build Coastguard Workerof _text_ in various parts of a _message_. 1111*912701f9SAndroid Build Coastguard WorkerA _literal_ can appear 1112*912701f9SAndroid Build Coastguard Workeras a _key_ value, 1113*912701f9SAndroid Build Coastguard Workeras the _operand_ of a _literal-expression_, 1114*912701f9SAndroid Build Coastguard Workeror in the value of an _option_. 1115*912701f9SAndroid Build Coastguard WorkerA _literal_ MAY include any Unicode code point 1116*912701f9SAndroid Build Coastguard Workerexcept for U+0000 NULL or the surrogate code points U+D800 through U+DFFF. 1117*912701f9SAndroid Build Coastguard Worker 1118*912701f9SAndroid Build Coastguard WorkerAll code points are preserved. 1119*912701f9SAndroid Build Coastguard Worker 1120*912701f9SAndroid Build Coastguard WorkerA **_<dfn>quoted</dfn>_** literal begins and ends with U+005E VERTICAL BAR `|`. 1121*912701f9SAndroid Build Coastguard WorkerThe characters `\` and `|` within a _quoted_ literal MUST be 1122*912701f9SAndroid Build Coastguard Workerescaped as `\\` and `\|`. 1123*912701f9SAndroid Build Coastguard Worker 1124*912701f9SAndroid Build Coastguard WorkerAn **_<dfn>unquoted</dfn>_** literal is a _literal_ that does not require the `|` 1125*912701f9SAndroid Build Coastguard Workerquotes around it to be distinct from the rest of the _message_ syntax. 1126*912701f9SAndroid Build Coastguard WorkerAn _unquoted_ MAY be used when the content of the _literal_ 1127*912701f9SAndroid Build Coastguard Workercontains no whitespace and otherwise matches the `unquoted` production. 1128*912701f9SAndroid Build Coastguard WorkerAny _unquoted_ literal MAY be _quoted_. 1129*912701f9SAndroid Build Coastguard WorkerImplementations MUST NOT distinguish between _quoted_ and _unquoted_ literals 1130*912701f9SAndroid Build Coastguard Workerthat have the same sequence of code points. 1131*912701f9SAndroid Build Coastguard Worker 1132*912701f9SAndroid Build Coastguard Worker_Unquoted_ literals can contain a _name_ or consist of a _number-literal_. 1133*912701f9SAndroid Build Coastguard WorkerA _number-literal_ uses the same syntax as JSON and is intended for the encoding 1134*912701f9SAndroid Build Coastguard Workerof number values in _operands_ or _options_, or as _keys_ for _variants_. 1135*912701f9SAndroid Build Coastguard Worker 1136*912701f9SAndroid Build Coastguard Worker```abnf 1137*912701f9SAndroid Build Coastguard Workerliteral = quoted / unquoted 1138*912701f9SAndroid Build Coastguard Workerquoted = "|" *(quoted-char / quoted-escape) "|" 1139*912701f9SAndroid Build Coastguard Workerunquoted = name / number-literal 1140*912701f9SAndroid Build Coastguard Workernumber-literal = ["-"] (%x30 / (%x31-39 *DIGIT)) ["." 1*DIGIT] [%i"e" ["-" / "+"] 1*DIGIT] 1141*912701f9SAndroid Build Coastguard Worker``` 1142*912701f9SAndroid Build Coastguard Worker 1143*912701f9SAndroid Build Coastguard Worker#### Names and Identifiers 1144*912701f9SAndroid Build Coastguard Worker 1145*912701f9SAndroid Build Coastguard WorkerAn **_<dfn>identifier</dfn>_** is a character sequence that 1146*912701f9SAndroid Build Coastguard Workeridentifies a _function_, _markup_, or _option_. 1147*912701f9SAndroid Build Coastguard WorkerEach _identifier_ consists of a _name_ optionally preceeded by 1148*912701f9SAndroid Build Coastguard Workera _namespace_. 1149*912701f9SAndroid Build Coastguard WorkerWhen present, the _namespace_ is separated from the _name_ by a 1150*912701f9SAndroid Build Coastguard WorkerU+003A COLON `:`. 1151*912701f9SAndroid Build Coastguard WorkerBuilt-in _functions_ and their _options_ do not have a _namespace_ identifier. 1152*912701f9SAndroid Build Coastguard Worker 1153*912701f9SAndroid Build Coastguard WorkerThe _namespace_ `u` (U+0075 LATIN SMALL LETTER U) 1154*912701f9SAndroid Build Coastguard Workeris reserved for future standardization. 1155*912701f9SAndroid Build Coastguard Worker 1156*912701f9SAndroid Build Coastguard Worker_Function_ _identifiers_ are prefixed with `:`. 1157*912701f9SAndroid Build Coastguard Worker_Markup_ _identifiers_ are prefixed with `#` or `/`. 1158*912701f9SAndroid Build Coastguard Worker_Option_ _identifiers_ have no prefix. 1159*912701f9SAndroid Build Coastguard Worker 1160*912701f9SAndroid Build Coastguard WorkerA **_<dfn>name</dfn>_** is a character sequence used in an _identifier_ 1161*912701f9SAndroid Build Coastguard Workeror as the name for a _variable_ 1162*912701f9SAndroid Build Coastguard Workeror the value of an _unquoted_ _literal_. 1163*912701f9SAndroid Build Coastguard Worker 1164*912701f9SAndroid Build Coastguard Worker_Variable_ names are prefixed with `$`. 1165*912701f9SAndroid Build Coastguard Worker 1166*912701f9SAndroid Build Coastguard WorkerValid content for _names_ is based on <cite>Namespaces in XML 1.0</cite>'s 1167*912701f9SAndroid Build Coastguard Worker[NCName](https://www.w3.org/TR/xml-names/#NT-NCName). 1168*912701f9SAndroid Build Coastguard WorkerThis is different from XML's [Name](https://www.w3.org/TR/xml/#NT-Name) 1169*912701f9SAndroid Build Coastguard Workerin that it MUST NOT contain a U+003A COLON `:`. 1170*912701f9SAndroid Build Coastguard WorkerOtherwise, the set of characters allowed in a _name_ is large. 1171*912701f9SAndroid Build Coastguard Worker 1172*912701f9SAndroid Build Coastguard Worker> [!NOTE] 1173*912701f9SAndroid Build Coastguard Worker> _External variables_ can be passed in that are not valid _names_. 1174*912701f9SAndroid Build Coastguard Worker> Such variables cannot be referenced in a _message_, 1175*912701f9SAndroid Build Coastguard Worker> but are not otherwise errors. 1176*912701f9SAndroid Build Coastguard Worker 1177*912701f9SAndroid Build Coastguard WorkerExamples: 1178*912701f9SAndroid Build Coastguard Worker> A variable: 1179*912701f9SAndroid Build Coastguard Worker>``` 1180*912701f9SAndroid Build Coastguard Worker> This has a {$variable} 1181*912701f9SAndroid Build Coastguard Worker>``` 1182*912701f9SAndroid Build Coastguard Worker> A function: 1183*912701f9SAndroid Build Coastguard Worker> ``` 1184*912701f9SAndroid Build Coastguard Worker> This has a {:function} 1185*912701f9SAndroid Build Coastguard Worker> ``` 1186*912701f9SAndroid Build Coastguard Worker> An add-on function from the `icu` namespace: 1187*912701f9SAndroid Build Coastguard Worker> ``` 1188*912701f9SAndroid Build Coastguard Worker> This has a {:icu:function} 1189*912701f9SAndroid Build Coastguard Worker> ``` 1190*912701f9SAndroid Build Coastguard Worker> An option and an add-on option: 1191*912701f9SAndroid Build Coastguard Worker> ``` 1192*912701f9SAndroid Build Coastguard Worker> This has {:options option=value icu:option=add_on} 1193*912701f9SAndroid Build Coastguard Worker> ``` 1194*912701f9SAndroid Build Coastguard Worker 1195*912701f9SAndroid Build Coastguard WorkerSupport for _namespaces_ and their interpretation is implementation-defined 1196*912701f9SAndroid Build Coastguard Workerin this release. 1197*912701f9SAndroid Build Coastguard Worker 1198*912701f9SAndroid Build Coastguard Worker```abnf 1199*912701f9SAndroid Build Coastguard Workervariable = "$" name 1200*912701f9SAndroid Build Coastguard Workeroption = identifier [s] "=" [s] (literal / variable) 1201*912701f9SAndroid Build Coastguard Worker 1202*912701f9SAndroid Build Coastguard Workeridentifier = [namespace ":"] name 1203*912701f9SAndroid Build Coastguard Workernamespace = name 1204*912701f9SAndroid Build Coastguard Workername = name-start *name-char 1205*912701f9SAndroid Build Coastguard Workername-start = ALPHA / "_" 1206*912701f9SAndroid Build Coastguard Worker / %xC0-D6 / %xD8-F6 / %xF8-2FF 1207*912701f9SAndroid Build Coastguard Worker / %x370-37D / %x37F-1FFF / %x200C-200D 1208*912701f9SAndroid Build Coastguard Worker / %x2070-218F / %x2C00-2FEF / %x3001-D7FF 1209*912701f9SAndroid Build Coastguard Worker / %xF900-FDCF / %xFDF0-FFFC / %x10000-EFFFF 1210*912701f9SAndroid Build Coastguard Workername-char = name-start / DIGIT / "-" / "." 1211*912701f9SAndroid Build Coastguard Worker / %xB7 / %x300-36F / %x203F-2040 1212*912701f9SAndroid Build Coastguard Worker``` 1213*912701f9SAndroid Build Coastguard Worker 1214*912701f9SAndroid Build Coastguard Worker#### Escape Sequences 1215*912701f9SAndroid Build Coastguard Worker 1216*912701f9SAndroid Build Coastguard WorkerAn **_<dfn>escape sequence</dfn>_** is a two-character sequence starting with 1217*912701f9SAndroid Build Coastguard WorkerU+005C REVERSE SOLIDUS `\`. 1218*912701f9SAndroid Build Coastguard Worker 1219*912701f9SAndroid Build Coastguard WorkerAn _escape sequence_ allows the appearance of lexically meaningful characters 1220*912701f9SAndroid Build Coastguard Workerin the body of _text_, _quoted_, or _reserved_ (which includes, in this case, 1221*912701f9SAndroid Build Coastguard Worker_private-use_) sequences respectively: 1222*912701f9SAndroid Build Coastguard Worker 1223*912701f9SAndroid Build Coastguard Worker```abnf 1224*912701f9SAndroid Build Coastguard Workertext-escape = backslash ( backslash / "{" / "}" ) 1225*912701f9SAndroid Build Coastguard Workerquoted-escape = backslash ( backslash / "|" ) 1226*912701f9SAndroid Build Coastguard Workerreserved-escape = backslash ( backslash / "{" / "|" / "}" ) 1227*912701f9SAndroid Build Coastguard Workerbackslash = %x5C ; U+005C REVERSE SOLIDUS "\" 1228*912701f9SAndroid Build Coastguard Worker``` 1229*912701f9SAndroid Build Coastguard Worker 1230*912701f9SAndroid Build Coastguard Worker#### Whitespace 1231*912701f9SAndroid Build Coastguard Worker 1232*912701f9SAndroid Build Coastguard Worker**_<dfn>Whitespace</dfn>_** is defined as one or more of 1233*912701f9SAndroid Build Coastguard WorkerU+0009 CHARACTER TABULATION (tab), 1234*912701f9SAndroid Build Coastguard WorkerU+000A LINE FEED (new line), 1235*912701f9SAndroid Build Coastguard WorkerU+000D CARRIAGE RETURN, 1236*912701f9SAndroid Build Coastguard WorkerU+3000 IDEOGRAPHIC SPACE, 1237*912701f9SAndroid Build Coastguard Workeror U+0020 SPACE. 1238*912701f9SAndroid Build Coastguard Worker 1239*912701f9SAndroid Build Coastguard WorkerInside _patterns_ and _quoted literals_, 1240*912701f9SAndroid Build Coastguard Workerwhitespace is part of the content and is recorded and stored verbatim. 1241*912701f9SAndroid Build Coastguard WorkerWhitespace is not significant outside translatable text, except where required by the syntax. 1242*912701f9SAndroid Build Coastguard Worker 1243*912701f9SAndroid Build Coastguard Worker> [!NOTE] 1244*912701f9SAndroid Build Coastguard Worker> The character U+3000 IDEOGRAPHIC SPACE is included in whitespace for 1245*912701f9SAndroid Build Coastguard Worker> compatibility with certain East Asian keyboards and input methods, 1246*912701f9SAndroid Build Coastguard Worker> in which users might accidentally create these characters in a _message_. 1247*912701f9SAndroid Build Coastguard Worker 1248*912701f9SAndroid Build Coastguard Worker```abnf 1249*912701f9SAndroid Build Coastguard Workers = 1*( SP / HTAB / CR / LF / %x3000 ) 1250*912701f9SAndroid Build Coastguard Worker``` 1251*912701f9SAndroid Build Coastguard Worker 1252*912701f9SAndroid Build Coastguard Worker## Complete ABNF 1253*912701f9SAndroid Build Coastguard Worker 1254*912701f9SAndroid Build Coastguard WorkerThe grammar below uses the ABNF notation [[STD68](https://www.rfc-editor.org/info/std68)], 1255*912701f9SAndroid Build Coastguard Workerincluding the modifications found in [RFC 7405](https://www.rfc-editor.org/rfc/rfc7405). 1256*912701f9SAndroid Build Coastguard Worker 1257*912701f9SAndroid Build Coastguard WorkerRFC7405 defines a variation of ABNF that is case-sensitive. 1258*912701f9SAndroid Build Coastguard WorkerSome ABNF tools are only compatible with the specification found in 1259*912701f9SAndroid Build Coastguard Worker[RFC 5234](https://www.rfc-editor.org/rfc/rfc5234). 1260*912701f9SAndroid Build Coastguard WorkerTo make `message.abnf` compatible with that version of ABNF, replace 1261*912701f9SAndroid Build Coastguard Workerthe rules of the same name with this block: 1262*912701f9SAndroid Build Coastguard Worker 1263*912701f9SAndroid Build Coastguard Worker```abnf 1264*912701f9SAndroid Build Coastguard Workerinput = %x2E.69.6E.70.75.74 ; ".input" 1265*912701f9SAndroid Build Coastguard Workerlocal = %x2E.6C.6F.63.61.6C ; ".local" 1266*912701f9SAndroid Build Coastguard Workermatch = %x2E.6D.61.74.63.68 ; ".match" 1267*912701f9SAndroid Build Coastguard Worker``` 1268*912701f9SAndroid Build Coastguard Worker 1269*912701f9SAndroid Build Coastguard Worker### `message.abnf` 1270*912701f9SAndroid Build Coastguard Worker 1271*912701f9SAndroid Build Coastguard Worker```abnf 1272*912701f9SAndroid Build Coastguard Workermessage = simple-message / complex-message 1273*912701f9SAndroid Build Coastguard Worker 1274*912701f9SAndroid Build Coastguard Workersimple-message = [simple-start pattern] 1275*912701f9SAndroid Build Coastguard Workersimple-start = simple-start-char / text-escape / placeholder 1276*912701f9SAndroid Build Coastguard Workerpattern = *(text-char / text-escape / placeholder) 1277*912701f9SAndroid Build Coastguard Workerplaceholder = expression / markup 1278*912701f9SAndroid Build Coastguard Worker 1279*912701f9SAndroid Build Coastguard Workercomplex-message = *(declaration [s]) complex-body 1280*912701f9SAndroid Build Coastguard Workerdeclaration = input-declaration / local-declaration / reserved-statement 1281*912701f9SAndroid Build Coastguard Workercomplex-body = quoted-pattern / matcher 1282*912701f9SAndroid Build Coastguard Worker 1283*912701f9SAndroid Build Coastguard Workerinput-declaration = input [s] variable-expression 1284*912701f9SAndroid Build Coastguard Workerlocal-declaration = local s variable [s] "=" [s] expression 1285*912701f9SAndroid Build Coastguard Worker 1286*912701f9SAndroid Build Coastguard Workerquoted-pattern = "{{" pattern "}}" 1287*912701f9SAndroid Build Coastguard Worker 1288*912701f9SAndroid Build Coastguard Workermatcher = match-statement 1*([s] variant) 1289*912701f9SAndroid Build Coastguard Workermatch-statement = match 1*([s] selector) 1290*912701f9SAndroid Build Coastguard Workerselector = expression 1291*912701f9SAndroid Build Coastguard Workervariant = key *(s key) [s] quoted-pattern 1292*912701f9SAndroid Build Coastguard Workerkey = literal / "*" 1293*912701f9SAndroid Build Coastguard Worker 1294*912701f9SAndroid Build Coastguard Worker; Expressions 1295*912701f9SAndroid Build Coastguard Workerexpression = literal-expression 1296*912701f9SAndroid Build Coastguard Worker / variable-expression 1297*912701f9SAndroid Build Coastguard Worker / annotation-expression 1298*912701f9SAndroid Build Coastguard Workerliteral-expression = "{" [s] literal [s annotation] *(s attribute) [s] "}" 1299*912701f9SAndroid Build Coastguard Workervariable-expression = "{" [s] variable [s annotation] *(s attribute) [s] "}" 1300*912701f9SAndroid Build Coastguard Workerannotation-expression = "{" [s] annotation *(s attribute) [s] "}" 1301*912701f9SAndroid Build Coastguard Worker 1302*912701f9SAndroid Build Coastguard Workerannotation = function 1303*912701f9SAndroid Build Coastguard Worker / private-use-annotation 1304*912701f9SAndroid Build Coastguard Worker / reserved-annotation 1305*912701f9SAndroid Build Coastguard Worker 1306*912701f9SAndroid Build Coastguard Workermarkup = "{" [s] "#" identifier *(s option) *(s attribute) [s] ["/"] "}" ; open and standalone 1307*912701f9SAndroid Build Coastguard Worker / "{" [s] "/" identifier *(s option) *(s attribute) [s] "}" ; close 1308*912701f9SAndroid Build Coastguard Worker 1309*912701f9SAndroid Build Coastguard Worker; Expression and literal parts 1310*912701f9SAndroid Build Coastguard Workerfunction = ":" identifier *(s option) 1311*912701f9SAndroid Build Coastguard Workeroption = identifier [s] "=" [s] (literal / variable) 1312*912701f9SAndroid Build Coastguard Worker; Attributes are reserved for future standardization 1313*912701f9SAndroid Build Coastguard Workerattribute = "@" identifier [[s] "=" [s] (literal / variable)] 1314*912701f9SAndroid Build Coastguard Worker 1315*912701f9SAndroid Build Coastguard Workervariable = "$" name 1316*912701f9SAndroid Build Coastguard Workerliteral = quoted / unquoted 1317*912701f9SAndroid Build Coastguard Workerquoted = "|" *(quoted-char / quoted-escape) "|" 1318*912701f9SAndroid Build Coastguard Workerunquoted = name / number-literal 1319*912701f9SAndroid Build Coastguard Worker; number-literal matches JSON number (https://www.rfc-editor.org/rfc/rfc8259#section-6) 1320*912701f9SAndroid Build Coastguard Workernumber-literal = ["-"] (%x30 / (%x31-39 *DIGIT)) ["." 1*DIGIT] [%i"e" ["-" / "+"] 1*DIGIT] 1321*912701f9SAndroid Build Coastguard Worker 1322*912701f9SAndroid Build Coastguard Worker; Keywords; Note that these are case-sensitive 1323*912701f9SAndroid Build Coastguard Workerinput = %s".input" 1324*912701f9SAndroid Build Coastguard Workerlocal = %s".local" 1325*912701f9SAndroid Build Coastguard Workermatch = %s".match" 1326*912701f9SAndroid Build Coastguard Worker 1327*912701f9SAndroid Build Coastguard Worker; Reserve additional .keywords for use by future versions of this specification. 1328*912701f9SAndroid Build Coastguard Workerreserved-statement = reserved-keyword [s reserved-body] 1*([s] expression) 1329*912701f9SAndroid Build Coastguard Worker; Note that the following production is a simplification, 1330*912701f9SAndroid Build Coastguard Worker; as this rule MUST NOT be considered to match existing keywords 1331*912701f9SAndroid Build Coastguard Worker; (`.input`, `.local`, and `.match`). 1332*912701f9SAndroid Build Coastguard Workerreserved-keyword = "." name 1333*912701f9SAndroid Build Coastguard Worker 1334*912701f9SAndroid Build Coastguard Worker; Reserve additional sigils for use by future versions of this specification. 1335*912701f9SAndroid Build Coastguard Workerreserved-annotation = reserved-annotation-start [[s] reserved-body] 1336*912701f9SAndroid Build Coastguard Workerreserved-annotation-start = "!" / "%" / "*" / "+" / "<" / ">" / "?" / "~" 1337*912701f9SAndroid Build Coastguard Worker 1338*912701f9SAndroid Build Coastguard Worker; Reserve sigils for private-use by implementations. 1339*912701f9SAndroid Build Coastguard Workerprivate-use-annotation = private-start [[s] reserved-body] 1340*912701f9SAndroid Build Coastguard Workerprivate-start = "^" / "&" 1341*912701f9SAndroid Build Coastguard Workerreserved-body = reserved-body-part *([s] reserved-body-part) 1342*912701f9SAndroid Build Coastguard Workerreserved-body-part = reserved-char / reserved-escape / quoted 1343*912701f9SAndroid Build Coastguard Worker 1344*912701f9SAndroid Build Coastguard Worker; Names and identifiers 1345*912701f9SAndroid Build Coastguard Worker; identifier matches https://www.w3.org/TR/REC-xml-names/#NT-QName 1346*912701f9SAndroid Build Coastguard Worker; name matches https://www.w3.org/TR/REC-xml-names/#NT-NCName 1347*912701f9SAndroid Build Coastguard Workeridentifier = [namespace ":"] name 1348*912701f9SAndroid Build Coastguard Workernamespace = name 1349*912701f9SAndroid Build Coastguard Workername = name-start *name-char 1350*912701f9SAndroid Build Coastguard Workername-start = ALPHA / "_" 1351*912701f9SAndroid Build Coastguard Worker / %xC0-D6 / %xD8-F6 / %xF8-2FF 1352*912701f9SAndroid Build Coastguard Worker / %x370-37D / %x37F-1FFF / %x200C-200D 1353*912701f9SAndroid Build Coastguard Worker / %x2070-218F / %x2C00-2FEF / %x3001-D7FF 1354*912701f9SAndroid Build Coastguard Worker / %xF900-FDCF / %xFDF0-FFFC / %x10000-EFFFF 1355*912701f9SAndroid Build Coastguard Workername-char = name-start / DIGIT / "-" / "." 1356*912701f9SAndroid Build Coastguard Worker / %xB7 / %x300-36F / %x203F-2040 1357*912701f9SAndroid Build Coastguard Worker 1358*912701f9SAndroid Build Coastguard Worker; Restrictions on characters in various contexts 1359*912701f9SAndroid Build Coastguard Workersimple-start-char = content-char / s / "@" / "|" 1360*912701f9SAndroid Build Coastguard Workertext-char = content-char / s / "." / "@" / "|" 1361*912701f9SAndroid Build Coastguard Workerquoted-char = content-char / s / "." / "@" / "{" / "}" 1362*912701f9SAndroid Build Coastguard Workerreserved-char = content-char / "." 1363*912701f9SAndroid Build Coastguard Workercontent-char = %x01-08 ; omit NULL (%x00), HTAB (%x09) and LF (%x0A) 1364*912701f9SAndroid Build Coastguard Worker / %x0B-0C ; omit CR (%x0D) 1365*912701f9SAndroid Build Coastguard Worker / %x0E-1F ; omit SP (%x20) 1366*912701f9SAndroid Build Coastguard Worker / %x21-2D ; omit . (%x2E) 1367*912701f9SAndroid Build Coastguard Worker / %x2F-3F ; omit @ (%x40) 1368*912701f9SAndroid Build Coastguard Worker / %x41-5B ; omit \ (%x5C) 1369*912701f9SAndroid Build Coastguard Worker / %x5D-7A ; omit { | } (%x7B-7D) 1370*912701f9SAndroid Build Coastguard Worker / %x7E-2FFF ; omit IDEOGRAPHIC SPACE (%x3000) 1371*912701f9SAndroid Build Coastguard Worker / %x3001-D7FF ; omit surrogates 1372*912701f9SAndroid Build Coastguard Worker / %xE000-10FFFF 1373*912701f9SAndroid Build Coastguard Worker 1374*912701f9SAndroid Build Coastguard Worker; Character escapes 1375*912701f9SAndroid Build Coastguard Workertext-escape = backslash ( backslash / "{" / "}" ) 1376*912701f9SAndroid Build Coastguard Workerquoted-escape = backslash ( backslash / "|" ) 1377*912701f9SAndroid Build Coastguard Workerreserved-escape = backslash ( backslash / "{" / "|" / "}" ) 1378*912701f9SAndroid Build Coastguard Workerbackslash = %x5C ; U+005C REVERSE SOLIDUS "\" 1379*912701f9SAndroid Build Coastguard Worker 1380*912701f9SAndroid Build Coastguard Worker; Whitespace 1381*912701f9SAndroid Build Coastguard Workers = 1*( SP / HTAB / CR / LF / %x3000 ) 1382*912701f9SAndroid Build Coastguard Worker``` 1383*912701f9SAndroid Build Coastguard Worker 1384*912701f9SAndroid Build Coastguard Worker## Errors 1385*912701f9SAndroid Build Coastguard Worker 1386*912701f9SAndroid Build Coastguard WorkerErrors in messages and their formatting MAY occur and be detected 1387*912701f9SAndroid Build Coastguard Workerat different stages of processing. 1388*912701f9SAndroid Build Coastguard WorkerWhere available, 1389*912701f9SAndroid Build Coastguard Workerthe use of validation tools is recommended, 1390*912701f9SAndroid Build Coastguard Workeras early detection of errors makes their correction easier. 1391*912701f9SAndroid Build Coastguard Worker 1392*912701f9SAndroid Build Coastguard Worker### Error Handling 1393*912701f9SAndroid Build Coastguard Worker 1394*912701f9SAndroid Build Coastguard Worker_Syntax Errors_ and _Data Model Errors_ apply to all message processors, 1395*912701f9SAndroid Build Coastguard Workerand MUST be emitted as soon as possible. 1396*912701f9SAndroid Build Coastguard WorkerThe other error categories are only emitted during formatting, 1397*912701f9SAndroid Build Coastguard Workerbut it might be possible to detect them with validation tools. 1398*912701f9SAndroid Build Coastguard Worker 1399*912701f9SAndroid Build Coastguard WorkerDuring selection, an _expression_ handler MUST only emit _Resolution Errors_ and _Selection Errors_. 1400*912701f9SAndroid Build Coastguard WorkerDuring formatting, an _expression_ handler MUST only emit _Resolution Errors_ and _Formatting Errors_. 1401*912701f9SAndroid Build Coastguard Worker 1402*912701f9SAndroid Build Coastguard Worker_Resolution Errors_ and _Formatting Errors_ in _expressions_ that are not used 1403*912701f9SAndroid Build Coastguard Workerin _pattern selection_ or _formatting_ MAY be ignored, 1404*912701f9SAndroid Build Coastguard Workeras they do not affect the output of the formatter. 1405*912701f9SAndroid Build Coastguard Worker 1406*912701f9SAndroid Build Coastguard WorkerIn all cases, when encountering a runtime error, 1407*912701f9SAndroid Build Coastguard Workera message formatter MUST provide some representation of the message. 1408*912701f9SAndroid Build Coastguard WorkerAn informative error or errors MUST also be separately provided. 1409*912701f9SAndroid Build Coastguard Worker 1410*912701f9SAndroid Build Coastguard WorkerWhen a message contains more than one error, 1411*912701f9SAndroid Build Coastguard Workeror contains some error which leads to further errors, 1412*912701f9SAndroid Build Coastguard Workeran implementation which does not emit all of the errors 1413*912701f9SAndroid Build Coastguard WorkerSHOULD prioritise _Syntax Errors_ and _Data Model Errors_ over others. 1414*912701f9SAndroid Build Coastguard Worker 1415*912701f9SAndroid Build Coastguard WorkerWhen an error occurs within a _selector_, 1416*912701f9SAndroid Build Coastguard Workerthe _selector_ MUST NOT match any _variant_ _key_ other than the catch-all `*` 1417*912701f9SAndroid Build Coastguard Workerand a _Resolution Error_ or a _Selection Error_ MUST be emitted. 1418*912701f9SAndroid Build Coastguard Worker 1419*912701f9SAndroid Build Coastguard Worker### Syntax Errors 1420*912701f9SAndroid Build Coastguard Worker 1421*912701f9SAndroid Build Coastguard Worker**_<dfn>Syntax Errors</dfn>_** occur when the syntax representation of a message is not well-formed. 1422*912701f9SAndroid Build Coastguard Worker 1423*912701f9SAndroid Build Coastguard Worker> Example invalid messages resulting in a _Syntax Error_: 1424*912701f9SAndroid Build Coastguard Worker> 1425*912701f9SAndroid Build Coastguard Worker> ``` 1426*912701f9SAndroid Build Coastguard Worker> {{Missing end braces 1427*912701f9SAndroid Build Coastguard Worker> ``` 1428*912701f9SAndroid Build Coastguard Worker> 1429*912701f9SAndroid Build Coastguard Worker> ``` 1430*912701f9SAndroid Build Coastguard Worker> {{Missing one end brace} 1431*912701f9SAndroid Build Coastguard Worker> ``` 1432*912701f9SAndroid Build Coastguard Worker> 1433*912701f9SAndroid Build Coastguard Worker> ``` 1434*912701f9SAndroid Build Coastguard Worker> Unknown {{expression}} 1435*912701f9SAndroid Build Coastguard Worker> ``` 1436*912701f9SAndroid Build Coastguard Worker> 1437*912701f9SAndroid Build Coastguard Worker> ``` 1438*912701f9SAndroid Build Coastguard Worker> .local $var = {|no message body|} 1439*912701f9SAndroid Build Coastguard Worker> ``` 1440*912701f9SAndroid Build Coastguard Worker 1441*912701f9SAndroid Build Coastguard Worker### Data Model Errors 1442*912701f9SAndroid Build Coastguard Worker 1443*912701f9SAndroid Build Coastguard Worker**_<dfn>Data Model Errors</dfn>_** occur when a message is invalid due to 1444*912701f9SAndroid Build Coastguard Workerviolating one of the semantic requirements on its structure. 1445*912701f9SAndroid Build Coastguard Worker 1446*912701f9SAndroid Build Coastguard Worker#### Variant Key Mismatch 1447*912701f9SAndroid Build Coastguard Worker 1448*912701f9SAndroid Build Coastguard WorkerA **_<dfn>Variant Key Mismatch</dfn>_** occurs when the number of keys on a _variant_ 1449*912701f9SAndroid Build Coastguard Workerdoes not equal the number of _selectors_. 1450*912701f9SAndroid Build Coastguard Worker 1451*912701f9SAndroid Build Coastguard Worker> Example invalid messages resulting in a _Variant Key Mismatch_ error: 1452*912701f9SAndroid Build Coastguard Worker> 1453*912701f9SAndroid Build Coastguard Worker> ``` 1454*912701f9SAndroid Build Coastguard Worker> .match {$one :func} 1455*912701f9SAndroid Build Coastguard Worker> 1 2 {{Too many}} 1456*912701f9SAndroid Build Coastguard Worker> * {{Otherwise}} 1457*912701f9SAndroid Build Coastguard Worker> ``` 1458*912701f9SAndroid Build Coastguard Worker> 1459*912701f9SAndroid Build Coastguard Worker> ``` 1460*912701f9SAndroid Build Coastguard Worker> .match {$one :func} {$two :func} 1461*912701f9SAndroid Build Coastguard Worker> 1 2 {{Two keys}} 1462*912701f9SAndroid Build Coastguard Worker> * {{Missing a key}} 1463*912701f9SAndroid Build Coastguard Worker> * * {{Otherwise}} 1464*912701f9SAndroid Build Coastguard Worker> ``` 1465*912701f9SAndroid Build Coastguard Worker 1466*912701f9SAndroid Build Coastguard Worker#### Missing Fallback Variant 1467*912701f9SAndroid Build Coastguard Worker 1468*912701f9SAndroid Build Coastguard WorkerA **_<dfn>Missing Fallback Variant</dfn>_** error occurs when the message 1469*912701f9SAndroid Build Coastguard Workerdoes not include a _variant_ with only catch-all keys. 1470*912701f9SAndroid Build Coastguard Worker 1471*912701f9SAndroid Build Coastguard Worker> Example invalid messages resulting in a _Missing Fallback Variant_ error: 1472*912701f9SAndroid Build Coastguard Worker> 1473*912701f9SAndroid Build Coastguard Worker> ``` 1474*912701f9SAndroid Build Coastguard Worker> .match {$one :func} 1475*912701f9SAndroid Build Coastguard Worker> 1 {{Value is one}} 1476*912701f9SAndroid Build Coastguard Worker> 2 {{Value is two}} 1477*912701f9SAndroid Build Coastguard Worker> ``` 1478*912701f9SAndroid Build Coastguard Worker> 1479*912701f9SAndroid Build Coastguard Worker> ``` 1480*912701f9SAndroid Build Coastguard Worker> .match {$one :func} {$two :func} 1481*912701f9SAndroid Build Coastguard Worker> 1 * {{First is one}} 1482*912701f9SAndroid Build Coastguard Worker> * 1 {{Second is one}} 1483*912701f9SAndroid Build Coastguard Worker> ``` 1484*912701f9SAndroid Build Coastguard Worker 1485*912701f9SAndroid Build Coastguard Worker#### Missing Selector Annotation 1486*912701f9SAndroid Build Coastguard Worker 1487*912701f9SAndroid Build Coastguard WorkerA **_<dfn>Missing Selector Annotation</dfn>_** error occurs when the _message_ 1488*912701f9SAndroid Build Coastguard Workercontains a _selector_ that does not have an _annotation_, 1489*912701f9SAndroid Build Coastguard Workeror contains a _variable_ that does not directly or indirectly reference a _declaration_ with an _annotation_. 1490*912701f9SAndroid Build Coastguard Worker 1491*912701f9SAndroid Build Coastguard Worker> Examples of invalid messages resulting in a _Missing Selector Annotation_ error: 1492*912701f9SAndroid Build Coastguard Worker> 1493*912701f9SAndroid Build Coastguard Worker> ``` 1494*912701f9SAndroid Build Coastguard Worker> .match {$one} 1495*912701f9SAndroid Build Coastguard Worker> 1 {{Value is one}} 1496*912701f9SAndroid Build Coastguard Worker> * {{Value is not one}} 1497*912701f9SAndroid Build Coastguard Worker> ``` 1498*912701f9SAndroid Build Coastguard Worker> 1499*912701f9SAndroid Build Coastguard Worker> ``` 1500*912701f9SAndroid Build Coastguard Worker> .local $one = {|The one|} 1501*912701f9SAndroid Build Coastguard Worker> .match {$one} 1502*912701f9SAndroid Build Coastguard Worker> 1 {{Value is one}} 1503*912701f9SAndroid Build Coastguard Worker> * {{Value is not one}} 1504*912701f9SAndroid Build Coastguard Worker> ``` 1505*912701f9SAndroid Build Coastguard Worker> 1506*912701f9SAndroid Build Coastguard Worker> ``` 1507*912701f9SAndroid Build Coastguard Worker> .input {$one} 1508*912701f9SAndroid Build Coastguard Worker> .match {$one} 1509*912701f9SAndroid Build Coastguard Worker> 1 {{Value is one}} 1510*912701f9SAndroid Build Coastguard Worker> * {{Value is not one}} 1511*912701f9SAndroid Build Coastguard Worker> ``` 1512*912701f9SAndroid Build Coastguard Worker 1513*912701f9SAndroid Build Coastguard Worker#### Duplicate Declaration 1514*912701f9SAndroid Build Coastguard Worker 1515*912701f9SAndroid Build Coastguard WorkerA **_<dfn>Duplicate Declaration</dfn>_** error occurs when a _variable_ is declared more than once. 1516*912701f9SAndroid Build Coastguard WorkerNote that an input _variable_ is implicitly declared when it is first used, 1517*912701f9SAndroid Build Coastguard Workerso explicitly declaring it after such use is also an error. 1518*912701f9SAndroid Build Coastguard Worker 1519*912701f9SAndroid Build Coastguard Worker> Examples of invalid messages resulting in a _Duplicate Declaration_ error: 1520*912701f9SAndroid Build Coastguard Worker> 1521*912701f9SAndroid Build Coastguard Worker> ``` 1522*912701f9SAndroid Build Coastguard Worker> .input {$var :number maximumFractionDigits=0} 1523*912701f9SAndroid Build Coastguard Worker> .input {$var :number minimumFractionDigits=0} 1524*912701f9SAndroid Build Coastguard Worker> {{Redeclaration of the same variable}} 1525*912701f9SAndroid Build Coastguard Worker> 1526*912701f9SAndroid Build Coastguard Worker> .local $var = {$ext :number maximumFractionDigits=0} 1527*912701f9SAndroid Build Coastguard Worker> .input {$var :number minimumFractionDigits=0} 1528*912701f9SAndroid Build Coastguard Worker> {{Redeclaration of a local variable}} 1529*912701f9SAndroid Build Coastguard Worker> 1530*912701f9SAndroid Build Coastguard Worker> .input {$var :number minimumFractionDigits=0} 1531*912701f9SAndroid Build Coastguard Worker> .local $var = {$ext :number maximumFractionDigits=0} 1532*912701f9SAndroid Build Coastguard Worker> {{Redeclaration of an input variable}} 1533*912701f9SAndroid Build Coastguard Worker> 1534*912701f9SAndroid Build Coastguard Worker> .input {$var :number minimumFractionDigits=$var2} 1535*912701f9SAndroid Build Coastguard Worker> .input {$var2 :number} 1536*912701f9SAndroid Build Coastguard Worker> {{Redeclaration of the implicit input variable $var2}} 1537*912701f9SAndroid Build Coastguard Worker> 1538*912701f9SAndroid Build Coastguard Worker> .local $var = {$ext :someFunction} 1539*912701f9SAndroid Build Coastguard Worker> .local $var = {$error} 1540*912701f9SAndroid Build Coastguard Worker> .local $var2 = {$var2 :error} 1541*912701f9SAndroid Build Coastguard Worker> {{{$var} cannot be redefined. {$var2} cannot refer to itself}} 1542*912701f9SAndroid Build Coastguard Worker> ``` 1543*912701f9SAndroid Build Coastguard Worker 1544*912701f9SAndroid Build Coastguard Worker#### Duplicate Option Name 1545*912701f9SAndroid Build Coastguard Worker 1546*912701f9SAndroid Build Coastguard WorkerA **_<dfn>Duplicate Option Name</dfn>_** error occurs when the same _identifier_ 1547*912701f9SAndroid Build Coastguard Workerappears on the left-hand side of more than one _option_ in the same _expression_. 1548*912701f9SAndroid Build Coastguard Worker 1549*912701f9SAndroid Build Coastguard Worker> Examples of invalid messages resulting in a _Duplicate Option Name_ error: 1550*912701f9SAndroid Build Coastguard Worker> 1551*912701f9SAndroid Build Coastguard Worker> ``` 1552*912701f9SAndroid Build Coastguard Worker> Value is {42 :number style=percent style=decimal} 1553*912701f9SAndroid Build Coastguard Worker> ``` 1554*912701f9SAndroid Build Coastguard Worker> 1555*912701f9SAndroid Build Coastguard Worker> ``` 1556*912701f9SAndroid Build Coastguard Worker> .local $foo = {horse :func one=1 two=2 one=1} 1557*912701f9SAndroid Build Coastguard Worker> {{This is {$foo}}} 1558*912701f9SAndroid Build Coastguard Worker> ``` 1559*912701f9SAndroid Build Coastguard Worker 1560*912701f9SAndroid Build Coastguard Worker### Resolution Errors 1561*912701f9SAndroid Build Coastguard Worker 1562*912701f9SAndroid Build Coastguard Worker**_<dfn>Resolution Errors</dfn>_** occur when the runtime value of a part of a message 1563*912701f9SAndroid Build Coastguard Workercannot be determined. 1564*912701f9SAndroid Build Coastguard Worker 1565*912701f9SAndroid Build Coastguard Worker#### Unresolved Variable 1566*912701f9SAndroid Build Coastguard Worker 1567*912701f9SAndroid Build Coastguard WorkerAn **_<dfn>Unresolved Variable</dfn>_** error occurs when a variable reference cannot be resolved. 1568*912701f9SAndroid Build Coastguard Worker 1569*912701f9SAndroid Build Coastguard Worker> For example, attempting to format either of the following messages 1570*912701f9SAndroid Build Coastguard Worker> would result in an _Unresolved Variable_ error if done within a context that 1571*912701f9SAndroid Build Coastguard Worker> does not provide for the variable reference `$var` to be successfully resolved: 1572*912701f9SAndroid Build Coastguard Worker> 1573*912701f9SAndroid Build Coastguard Worker> ``` 1574*912701f9SAndroid Build Coastguard Worker> The value is {$var}. 1575*912701f9SAndroid Build Coastguard Worker> ``` 1576*912701f9SAndroid Build Coastguard Worker> 1577*912701f9SAndroid Build Coastguard Worker> ``` 1578*912701f9SAndroid Build Coastguard Worker> .match {$var :func} 1579*912701f9SAndroid Build Coastguard Worker> 1 {{The value is one.}} 1580*912701f9SAndroid Build Coastguard Worker> * {{The value is not one.}} 1581*912701f9SAndroid Build Coastguard Worker> ``` 1582*912701f9SAndroid Build Coastguard Worker 1583*912701f9SAndroid Build Coastguard Worker#### Unknown Function 1584*912701f9SAndroid Build Coastguard Worker 1585*912701f9SAndroid Build Coastguard WorkerAn **_<dfn>Unknown Function</dfn>_** error occurs when an _expression_ includes 1586*912701f9SAndroid Build Coastguard Workera reference to a function which cannot be resolved. 1587*912701f9SAndroid Build Coastguard Worker 1588*912701f9SAndroid Build Coastguard Worker> For example, attempting to format either of the following messages 1589*912701f9SAndroid Build Coastguard Worker> would result in an _Unknown Function_ error if done within a context that 1590*912701f9SAndroid Build Coastguard Worker> does not provide for the function `:func` to be successfully resolved: 1591*912701f9SAndroid Build Coastguard Worker> 1592*912701f9SAndroid Build Coastguard Worker> ``` 1593*912701f9SAndroid Build Coastguard Worker> The value is {horse :func}. 1594*912701f9SAndroid Build Coastguard Worker> ``` 1595*912701f9SAndroid Build Coastguard Worker> 1596*912701f9SAndroid Build Coastguard Worker> ``` 1597*912701f9SAndroid Build Coastguard Worker> .match {|horse| :func} 1598*912701f9SAndroid Build Coastguard Worker> 1 {{The value is one.}} 1599*912701f9SAndroid Build Coastguard Worker> * {{The value is not one.}} 1600*912701f9SAndroid Build Coastguard Worker> ``` 1601*912701f9SAndroid Build Coastguard Worker 1602*912701f9SAndroid Build Coastguard Worker#### Unsupported Expression 1603*912701f9SAndroid Build Coastguard Worker 1604*912701f9SAndroid Build Coastguard WorkerAn **_<dfn>Unsupported Expression</dfn>_** error occurs when an expression uses 1605*912701f9SAndroid Build Coastguard Workersyntax reserved for future standardization, 1606*912701f9SAndroid Build Coastguard Workeror for private implementation use that is not supported by the current implementation. 1607*912701f9SAndroid Build Coastguard Worker 1608*912701f9SAndroid Build Coastguard Worker> For example, attempting to format this message 1609*912701f9SAndroid Build Coastguard Worker> would always result in an _Unsupported Expression_ error: 1610*912701f9SAndroid Build Coastguard Worker> 1611*912701f9SAndroid Build Coastguard Worker> ``` 1612*912701f9SAndroid Build Coastguard Worker> The value is {!horse}. 1613*912701f9SAndroid Build Coastguard Worker> ``` 1614*912701f9SAndroid Build Coastguard Worker> 1615*912701f9SAndroid Build Coastguard Worker> Attempting to format this message would result in an _Unsupported Expression_ error 1616*912701f9SAndroid Build Coastguard Worker> if done within a context that does not support the `^` private use sigil: 1617*912701f9SAndroid Build Coastguard Worker> 1618*912701f9SAndroid Build Coastguard Worker> ``` 1619*912701f9SAndroid Build Coastguard Worker> .match {|horse| ^private} 1620*912701f9SAndroid Build Coastguard Worker> 1 {{The value is one.}} 1621*912701f9SAndroid Build Coastguard Worker> * {{The value is not one.}} 1622*912701f9SAndroid Build Coastguard Worker> ``` 1623*912701f9SAndroid Build Coastguard Worker 1624*912701f9SAndroid Build Coastguard Worker#### Invalid Expression 1625*912701f9SAndroid Build Coastguard Worker 1626*912701f9SAndroid Build Coastguard WorkerAn **_<dfn>Invalid Expression</dfn>_** error occurs when a _message_ includes an _expression_ 1627*912701f9SAndroid Build Coastguard Workerwhose implementation-defined internal requirements produce an error during _function resolution_ 1628*912701f9SAndroid Build Coastguard Workeror when a _function_ returns a value (such as `null`) that the implementation does not support. 1629*912701f9SAndroid Build Coastguard Worker 1630*912701f9SAndroid Build Coastguard WorkerAn **_<dfn>Operand Mismatch Error</dfn>_** is an _Invalid Expression_ error that occurs when 1631*912701f9SAndroid Build Coastguard Workeran _operand_ provided to a _function_ during _function resolution_ does not match one of the 1632*912701f9SAndroid Build Coastguard Workerexpected implementation-defined types for that function; 1633*912701f9SAndroid Build Coastguard Workeror in which a literal _operand_ value does not have the required format 1634*912701f9SAndroid Build Coastguard Workerand thus cannot be processed into one of the expected implementation-defined types 1635*912701f9SAndroid Build Coastguard Workerfor that specific _function_. 1636*912701f9SAndroid Build Coastguard Worker 1637*912701f9SAndroid Build Coastguard Worker> For example, the following _message_ produces an _Operand Mismatch Error_ 1638*912701f9SAndroid Build Coastguard Worker> (a type of _Invalid Expression_ error) 1639*912701f9SAndroid Build Coastguard Worker> because the literal `|horse|` does not match the production `number-literal`, 1640*912701f9SAndroid Build Coastguard Worker> which is a requirement of the function `:number` for its operand: 1641*912701f9SAndroid Build Coastguard Worker> ``` 1642*912701f9SAndroid Build Coastguard Worker> .local $horse = {horse :number} 1643*912701f9SAndroid Build Coastguard Worker> {{You have a {$horse}.}} 1644*912701f9SAndroid Build Coastguard Worker> ``` 1645*912701f9SAndroid Build Coastguard Worker> The following _message_ might produce an _Invalid Expression_ error if the 1646*912701f9SAndroid Build Coastguard Worker> the function `:function` threw an exception or otherwise emitted an error 1647*912701f9SAndroid Build Coastguard Worker> rather than returning a valid value: 1648*912701f9SAndroid Build Coastguard Worker>``` 1649*912701f9SAndroid Build Coastguard Worker> {{This has an invalid expression {$var :function} because it has a bug in it.}} 1650*912701f9SAndroid Build Coastguard Worker>``` 1651*912701f9SAndroid Build Coastguard Worker 1652*912701f9SAndroid Build Coastguard Worker#### Unsupported Statement 1653*912701f9SAndroid Build Coastguard Worker 1654*912701f9SAndroid Build Coastguard WorkerAn **_<dfn>Unsupported Statement</dfn>_** error occurs when a message includes a _reserved statement_. 1655*912701f9SAndroid Build Coastguard Worker 1656*912701f9SAndroid Build Coastguard Worker> For example, attempting to format this message 1657*912701f9SAndroid Build Coastguard Worker> would always result in an _Unsupported Statement_ error: 1658*912701f9SAndroid Build Coastguard Worker> 1659*912701f9SAndroid Build Coastguard Worker> ``` 1660*912701f9SAndroid Build Coastguard Worker> .some {|horse|} 1661*912701f9SAndroid Build Coastguard Worker> {{The message body}} 1662*912701f9SAndroid Build Coastguard Worker> ``` 1663*912701f9SAndroid Build Coastguard Worker 1664*912701f9SAndroid Build Coastguard Worker### Selection Errors 1665*912701f9SAndroid Build Coastguard Worker 1666*912701f9SAndroid Build Coastguard Worker**_<dfn>Selection Errors</dfn>_** occur when message selection fails. 1667*912701f9SAndroid Build Coastguard Worker 1668*912701f9SAndroid Build Coastguard Worker> For example, attempting to format either of the following messages 1669*912701f9SAndroid Build Coastguard Worker> might result in a _Selection Error_ if done within a context that 1670*912701f9SAndroid Build Coastguard Worker> uses a `:number` selector function which requires its input to be numeric: 1671*912701f9SAndroid Build Coastguard Worker> 1672*912701f9SAndroid Build Coastguard Worker> ``` 1673*912701f9SAndroid Build Coastguard Worker> .match {|horse| :number} 1674*912701f9SAndroid Build Coastguard Worker> 1 {{The value is one.}} 1675*912701f9SAndroid Build Coastguard Worker> * {{The value is not one.}} 1676*912701f9SAndroid Build Coastguard Worker> ``` 1677*912701f9SAndroid Build Coastguard Worker> 1678*912701f9SAndroid Build Coastguard Worker> ``` 1679*912701f9SAndroid Build Coastguard Worker> .local $sel = {|horse| :number} 1680*912701f9SAndroid Build Coastguard Worker> .match {$sel} 1681*912701f9SAndroid Build Coastguard Worker> 1 {{The value is one.}} 1682*912701f9SAndroid Build Coastguard Worker> * {{The value is not one.}} 1683*912701f9SAndroid Build Coastguard Worker> ``` 1684*912701f9SAndroid Build Coastguard Worker 1685*912701f9SAndroid Build Coastguard Worker### Formatting Errors 1686*912701f9SAndroid Build Coastguard Worker 1687*912701f9SAndroid Build Coastguard Worker**_<dfn>Formatting Errors</dfn>_** occur during the formatting of a resolved value, 1688*912701f9SAndroid Build Coastguard Workerfor example when encountering a value with an unsupported type 1689*912701f9SAndroid Build Coastguard Workeror an internally inconsistent set of options. 1690*912701f9SAndroid Build Coastguard Worker 1691*912701f9SAndroid Build Coastguard Worker> For example, attempting to format any of the following messages 1692*912701f9SAndroid Build Coastguard Worker> might result in a _Formatting Error_ if done within a context that 1693*912701f9SAndroid Build Coastguard Worker> 1694*912701f9SAndroid Build Coastguard Worker> 1. provides for the variable reference `$user` to resolve to 1695*912701f9SAndroid Build Coastguard Worker> an object `{ name: 'Kat', id: 1234 }`, 1696*912701f9SAndroid Build Coastguard Worker> 2. provides for the variable reference `$field` to resolve to 1697*912701f9SAndroid Build Coastguard Worker> a string `'address'`, and 1698*912701f9SAndroid Build Coastguard Worker> 3. uses a `:get` formatting function which requires its argument to be an object and 1699*912701f9SAndroid Build Coastguard Worker> an option `field` to be provided with a string value, 1700*912701f9SAndroid Build Coastguard Worker> 1701*912701f9SAndroid Build Coastguard Worker> ``` 1702*912701f9SAndroid Build Coastguard Worker> Hello, {horse :get field=name}! 1703*912701f9SAndroid Build Coastguard Worker> ``` 1704*912701f9SAndroid Build Coastguard Worker> 1705*912701f9SAndroid Build Coastguard Worker> ``` 1706*912701f9SAndroid Build Coastguard Worker> Hello, {$user :get}! 1707*912701f9SAndroid Build Coastguard Worker> ``` 1708*912701f9SAndroid Build Coastguard Worker> 1709*912701f9SAndroid Build Coastguard Worker> ``` 1710*912701f9SAndroid Build Coastguard Worker> .local $id = {$user :get field=id} 1711*912701f9SAndroid Build Coastguard Worker> {{Hello, {$id :get field=name}!}} 1712*912701f9SAndroid Build Coastguard Worker> ``` 1713*912701f9SAndroid Build Coastguard Worker> 1714*912701f9SAndroid Build Coastguard Worker> ``` 1715*912701f9SAndroid Build Coastguard Worker> Your {$field} is {$id :get field=$field} 1716*912701f9SAndroid Build Coastguard Worker> ``` 1717*912701f9SAndroid Build Coastguard Worker 1718*912701f9SAndroid Build Coastguard Worker## Function Registry 1719*912701f9SAndroid Build Coastguard Worker 1720*912701f9SAndroid Build Coastguard WorkerImplementations and tooling can greatly benefit from a 1721*912701f9SAndroid Build Coastguard Workerstructured definition of formatting and matching functions available to messages at runtime. 1722*912701f9SAndroid Build Coastguard WorkerThis specification is intended to provide a mechanism for storing such declarations in a portable manner. 1723*912701f9SAndroid Build Coastguard Worker 1724*912701f9SAndroid Build Coastguard Worker### Goals 1725*912701f9SAndroid Build Coastguard Worker 1726*912701f9SAndroid Build Coastguard Worker_This section is non-normative._ 1727*912701f9SAndroid Build Coastguard Worker 1728*912701f9SAndroid Build Coastguard WorkerThe registry provides a machine-readable description of MessageFormat 2 extensions (custom functions), 1729*912701f9SAndroid Build Coastguard Workerin order to support the following goals and use-cases: 1730*912701f9SAndroid Build Coastguard Worker 1731*912701f9SAndroid Build Coastguard Worker- Validate semantic properties of messages. For example: 1732*912701f9SAndroid Build Coastguard Worker - Type-check values passed into functions. 1733*912701f9SAndroid Build Coastguard Worker - Validate that matching functions are only called in selectors. 1734*912701f9SAndroid Build Coastguard Worker - Validate that formatting functions are only called in placeholders. 1735*912701f9SAndroid Build Coastguard Worker - Verify the exhaustiveness of variant keys given a selector. 1736*912701f9SAndroid Build Coastguard Worker- Support the localization roundtrip. For example: 1737*912701f9SAndroid Build Coastguard Worker - Generate variant keys for a given locale during XLIFF extraction. 1738*912701f9SAndroid Build Coastguard Worker- Improve the authoring experience. For example: 1739*912701f9SAndroid Build Coastguard Worker - Forbid edits to certain function options (e.g. currency options). 1740*912701f9SAndroid Build Coastguard Worker - Autocomplete function and option names. 1741*912701f9SAndroid Build Coastguard Worker - Display on-hover tooltips for function signatures with documentation. 1742*912701f9SAndroid Build Coastguard Worker - Display/edit known message metadata. 1743*912701f9SAndroid Build Coastguard Worker - Restrict input in GUI by providing a dropdown with all viable option values. 1744*912701f9SAndroid Build Coastguard Worker 1745*912701f9SAndroid Build Coastguard Worker### Conformance and Use 1746*912701f9SAndroid Build Coastguard Worker 1747*912701f9SAndroid Build Coastguard Worker_This section is normative._ 1748*912701f9SAndroid Build Coastguard Worker 1749*912701f9SAndroid Build Coastguard WorkerTo be conformant with MessageFormat 2.0, an implementation MUST implement 1750*912701f9SAndroid Build Coastguard Workerthe _functions_, _options_ and _option_ values, _operands_ and outputs 1751*912701f9SAndroid Build Coastguard Workerdescribed in the section [Default Registry](#default-registry) below. 1752*912701f9SAndroid Build Coastguard Worker 1753*912701f9SAndroid Build Coastguard WorkerImplementations MAY implement additional _functions_ or additional _options_. 1754*912701f9SAndroid Build Coastguard WorkerIn particular, implementations are encouraged to provide feedback on proposed 1755*912701f9SAndroid Build Coastguard Worker_options_ and their values. 1756*912701f9SAndroid Build Coastguard Worker 1757*912701f9SAndroid Build Coastguard Worker> [!IMPORTANT] 1758*912701f9SAndroid Build Coastguard Worker> In the Tech Preview, the [registry data model](#registry-data-model) should 1759*912701f9SAndroid Build Coastguard Worker> be regarded as experimental. 1760*912701f9SAndroid Build Coastguard Worker> Changes to the format are expected during this period. 1761*912701f9SAndroid Build Coastguard Worker> Feedback on the registry's format and implementation is encouraged! 1762*912701f9SAndroid Build Coastguard Worker 1763*912701f9SAndroid Build Coastguard WorkerImplementations are not required to provide a machine-readable registry 1764*912701f9SAndroid Build Coastguard Workernor to read or interpret the registry data model in order to be conformant. 1765*912701f9SAndroid Build Coastguard Worker 1766*912701f9SAndroid Build Coastguard WorkerThe MessageFormat 2.0 Registry was created to describe 1767*912701f9SAndroid Build Coastguard Workerthe core set of formatting and selection _functions_, 1768*912701f9SAndroid Build Coastguard Workerincluding _operands_, _options_, and _option_ values. 1769*912701f9SAndroid Build Coastguard WorkerThis is the minimum set of functionality needed for conformance. 1770*912701f9SAndroid Build Coastguard WorkerBy using the same names and values, _messages_ can be used interchangeably 1771*912701f9SAndroid Build Coastguard Workerby different implementations, 1772*912701f9SAndroid Build Coastguard Workerregardless of programming language or runtime environment. 1773*912701f9SAndroid Build Coastguard WorkerThis ensures that developers do not have to relearn core MessageFormat syntax 1774*912701f9SAndroid Build Coastguard Workerand functionality when moving between platforms 1775*912701f9SAndroid Build Coastguard Workerand that translators do not need to know about the runtime environment for most 1776*912701f9SAndroid Build Coastguard Workerselection or formatting operations. 1777*912701f9SAndroid Build Coastguard Worker 1778*912701f9SAndroid Build Coastguard WorkerThe registry provides a machine-readable description of _functions_ 1779*912701f9SAndroid Build Coastguard Workersuitable for tools, such as those used in translation automation, so that 1780*912701f9SAndroid Build Coastguard Workervariant expansion and information about available _options_ and their effects 1781*912701f9SAndroid Build Coastguard Workerare available in the translation ecosystem. 1782*912701f9SAndroid Build Coastguard WorkerTo that end, implementations are strongly encouraged to provide appropriately 1783*912701f9SAndroid Build Coastguard Workertailored versions of the registry for consumption by tools 1784*912701f9SAndroid Build Coastguard Worker(even if not included in software distributions) 1785*912701f9SAndroid Build Coastguard Workerand to encourage any add-on or plug-in functionality to provide 1786*912701f9SAndroid Build Coastguard Workera registry to support localization tooling. 1787*912701f9SAndroid Build Coastguard Worker 1788*912701f9SAndroid Build Coastguard Worker### Registry Data Model 1789*912701f9SAndroid Build Coastguard Worker 1790*912701f9SAndroid Build Coastguard Worker_This section is non-normative._ 1791*912701f9SAndroid Build Coastguard Worker 1792*912701f9SAndroid Build Coastguard Worker> [!IMPORTANT] 1793*912701f9SAndroid Build Coastguard Worker> This part of the specification is not part of the Tech Preview. 1794*912701f9SAndroid Build Coastguard Worker 1795*912701f9SAndroid Build Coastguard WorkerThe registry contains descriptions of function signatures. 1796*912701f9SAndroid Build Coastguard Worker 1797*912701f9SAndroid Build Coastguard WorkerThe main building block of the registry is the `<function>` element. 1798*912701f9SAndroid Build Coastguard WorkerIt represents an implementation of a custom function available to translation at runtime. 1799*912701f9SAndroid Build Coastguard WorkerA function defines a human-readable `<description>` of its behavior 1800*912701f9SAndroid Build Coastguard Workerand one or more machine-readable _signatures_ of how to call it. 1801*912701f9SAndroid Build Coastguard WorkerNamed `<validationRule>` elements can optionally define regex validation rules for 1802*912701f9SAndroid Build Coastguard Workerliterals, option values, and variant keys. 1803*912701f9SAndroid Build Coastguard Worker 1804*912701f9SAndroid Build Coastguard WorkerMessageFormat 2 functions can be invoked in two contexts: 1805*912701f9SAndroid Build Coastguard Worker 1806*912701f9SAndroid Build Coastguard Worker- inside placeholders, to produce a part of the message's formatted output; 1807*912701f9SAndroid Build Coastguard Worker for example, a raw value of `|1.5|` may be formatted to `1,5` in a language which uses commas as decimal separators, 1808*912701f9SAndroid Build Coastguard Worker- inside selectors, to contribute to selecting the appropriate variant among all given variants. 1809*912701f9SAndroid Build Coastguard Worker 1810*912701f9SAndroid Build Coastguard WorkerA single _function name_ may be used in both contexts, 1811*912701f9SAndroid Build Coastguard Workerregardless of whether it's implemented as one or multiple functions. 1812*912701f9SAndroid Build Coastguard Worker 1813*912701f9SAndroid Build Coastguard WorkerA _signature_ defines one particular set of at most one argument and any number of named options 1814*912701f9SAndroid Build Coastguard Workerthat can be used together in a single call to the function. 1815*912701f9SAndroid Build Coastguard Worker`<formatSignature>` corresponds to a function call inside a placeholder inside translatable text. 1816*912701f9SAndroid Build Coastguard Worker`<matchSignature>` corresponds to a function call inside a selector. 1817*912701f9SAndroid Build Coastguard Worker 1818*912701f9SAndroid Build Coastguard WorkerA signature may define the positional argument of the function with the `<input>` element. 1819*912701f9SAndroid Build Coastguard WorkerIf the `<input>` element is not present, the function is defined as a nullary function. 1820*912701f9SAndroid Build Coastguard WorkerA signature may also define one or more `<option>` elements representing _named options_ to the function. 1821*912701f9SAndroid Build Coastguard WorkerAn option can be omitted in a call to the function, 1822*912701f9SAndroid Build Coastguard Workerunless the `required` attribute is present. 1823*912701f9SAndroid Build Coastguard WorkerThey accept either a finite enumeration of values (the `values` attribute) 1824*912701f9SAndroid Build Coastguard Workeror validate their input with a regular expression (the `validationRule` attribute). 1825*912701f9SAndroid Build Coastguard WorkerRead-only options (the `readonly` attribute) can be displayed to translators in CAT tools, but may not be edited. 1826*912701f9SAndroid Build Coastguard Worker 1827*912701f9SAndroid Build Coastguard WorkerAs the `<input>` and `<option>` rules may be locale-dependent, 1828*912701f9SAndroid Build Coastguard Workereach signature can include an `<override locales="...">` that extends and overrides 1829*912701f9SAndroid Build Coastguard Workerthe corresponding input and options rules. 1830*912701f9SAndroid Build Coastguard WorkerIf multiple `<override>` elements would match the current locale, 1831*912701f9SAndroid Build Coastguard Workeronly the first one is used. 1832*912701f9SAndroid Build Coastguard Worker 1833*912701f9SAndroid Build Coastguard WorkerMatching-function signatures additionally include one or more `<match>` elements 1834*912701f9SAndroid Build Coastguard Workerto define the keys against which they can match when used as selectors. 1835*912701f9SAndroid Build Coastguard Worker 1836*912701f9SAndroid Build Coastguard WorkerFunctions may also include `<alias>` definitions, 1837*912701f9SAndroid Build Coastguard Workerwhich provide shorthands for commonly used option baskets. 1838*912701f9SAndroid Build Coastguard WorkerAn _alias name_ may be used equivalently to a _function name_ in messages. 1839*912701f9SAndroid Build Coastguard WorkerIts `<setOption>` values are always set, and may not be overridden in message annotations. 1840*912701f9SAndroid Build Coastguard Worker 1841*912701f9SAndroid Build Coastguard WorkerIf a `<function>`, `<input>` or `<option>` includes multiple `<description>` elements, 1842*912701f9SAndroid Build Coastguard Workereach SHOULD have a different `xml:lang` attribute value. 1843*912701f9SAndroid Build Coastguard WorkerThis allows for the descriptions of these elements to be themselves localized 1844*912701f9SAndroid Build Coastguard Workeraccording to the preferred locale of the message authors and editors. 1845*912701f9SAndroid Build Coastguard Worker 1846*912701f9SAndroid Build Coastguard Worker### Example 1847*912701f9SAndroid Build Coastguard Worker 1848*912701f9SAndroid Build Coastguard WorkerThe following `registry.xml` is an example of a registry file 1849*912701f9SAndroid Build Coastguard Workerwhich may be provided by an implementation to describe its built-in functions. 1850*912701f9SAndroid Build Coastguard WorkerFor the sake of brevity, only `locales="en"` is considered. 1851*912701f9SAndroid Build Coastguard Worker 1852*912701f9SAndroid Build Coastguard Worker```xml 1853*912701f9SAndroid Build Coastguard Worker<?xml version="1.0" encoding="UTF-8" ?> 1854*912701f9SAndroid Build Coastguard Worker<!DOCTYPE registry SYSTEM "./registry.dtd"> 1855*912701f9SAndroid Build Coastguard Worker 1856*912701f9SAndroid Build Coastguard Worker<registry xml:lang="en"> 1857*912701f9SAndroid Build Coastguard Worker <function name="platform"> 1858*912701f9SAndroid Build Coastguard Worker <description>Match the current OS.</description> 1859*912701f9SAndroid Build Coastguard Worker <matchSignature> 1860*912701f9SAndroid Build Coastguard Worker <match values="windows linux macos android ios"/> 1861*912701f9SAndroid Build Coastguard Worker </matchSignature> 1862*912701f9SAndroid Build Coastguard Worker </function> 1863*912701f9SAndroid Build Coastguard Worker 1864*912701f9SAndroid Build Coastguard Worker <validationRule id="anyNumber" regex="-?[0-9]+(\.[0-9]+)"/> 1865*912701f9SAndroid Build Coastguard Worker <validationRule id="positiveInteger" regex="[0-9]+"/> 1866*912701f9SAndroid Build Coastguard Worker <validationRule id="currencyCode" regex="[A-Z]{3}"/> 1867*912701f9SAndroid Build Coastguard Worker 1868*912701f9SAndroid Build Coastguard Worker <function name="number"> 1869*912701f9SAndroid Build Coastguard Worker <description> 1870*912701f9SAndroid Build Coastguard Worker Format a number. 1871*912701f9SAndroid Build Coastguard Worker Match a **formatted** numerical value against CLDR plural categories or against a number literal. 1872*912701f9SAndroid Build Coastguard Worker </description> 1873*912701f9SAndroid Build Coastguard Worker 1874*912701f9SAndroid Build Coastguard Worker <matchSignature> 1875*912701f9SAndroid Build Coastguard Worker <input validationRule="anyNumber"/> 1876*912701f9SAndroid Build Coastguard Worker <option name="type" values="cardinal ordinal"/> 1877*912701f9SAndroid Build Coastguard Worker <option name="minimumIntegerDigits" validationRule="positiveInteger"/> 1878*912701f9SAndroid Build Coastguard Worker <option name="minimumFractionDigits" validationRule="positiveInteger"/> 1879*912701f9SAndroid Build Coastguard Worker <option name="maximumFractionDigits" validationRule="positiveInteger"/> 1880*912701f9SAndroid Build Coastguard Worker <option name="minimumSignificantDigits" validationRule="positiveInteger"/> 1881*912701f9SAndroid Build Coastguard Worker <option name="maximumSignificantDigits" validationRule="positiveInteger"/> 1882*912701f9SAndroid Build Coastguard Worker <!-- Since this applies to both cardinal and ordinal, all plural options are valid. --> 1883*912701f9SAndroid Build Coastguard Worker <match locales="en" values="one two few other" validationRule="anyNumber"/> 1884*912701f9SAndroid Build Coastguard Worker <match values="zero one two few many other" validationRule="anyNumber"/> 1885*912701f9SAndroid Build Coastguard Worker </matchSignature> 1886*912701f9SAndroid Build Coastguard Worker 1887*912701f9SAndroid Build Coastguard Worker <formatSignature> 1888*912701f9SAndroid Build Coastguard Worker <input validationRule="anyNumber"/> 1889*912701f9SAndroid Build Coastguard Worker <option name="minimumIntegerDigits" validationRule="positiveInteger"/> 1890*912701f9SAndroid Build Coastguard Worker <option name="minimumFractionDigits" validationRule="positiveInteger"/> 1891*912701f9SAndroid Build Coastguard Worker <option name="maximumFractionDigits" validationRule="positiveInteger"/> 1892*912701f9SAndroid Build Coastguard Worker <option name="minimumSignificantDigits" validationRule="positiveInteger"/> 1893*912701f9SAndroid Build Coastguard Worker <option name="maximumSignificantDigits" validationRule="positiveInteger"/> 1894*912701f9SAndroid Build Coastguard Worker <option name="style" readonly="true" values="decimal currency percent unit" default="decimal"/> 1895*912701f9SAndroid Build Coastguard Worker <option name="currency" readonly="true" validationRule="currencyCode"/> 1896*912701f9SAndroid Build Coastguard Worker </formatSignature> 1897*912701f9SAndroid Build Coastguard Worker 1898*912701f9SAndroid Build Coastguard Worker <alias name="integer"> 1899*912701f9SAndroid Build Coastguard Worker <description>Locale-sensitive integral number formatting</description> 1900*912701f9SAndroid Build Coastguard Worker <setOption name="maximumFractionDigits" value="0" /> 1901*912701f9SAndroid Build Coastguard Worker <setOption name="style" value="decimal" /> 1902*912701f9SAndroid Build Coastguard Worker </alias> 1903*912701f9SAndroid Build Coastguard Worker </function> 1904*912701f9SAndroid Build Coastguard Worker</registry> 1905*912701f9SAndroid Build Coastguard Worker``` 1906*912701f9SAndroid Build Coastguard Worker 1907*912701f9SAndroid Build Coastguard WorkerGiven the above description, the `:number` function is defined to work both in a selector and a placeholder: 1908*912701f9SAndroid Build Coastguard Worker 1909*912701f9SAndroid Build Coastguard Worker``` 1910*912701f9SAndroid Build Coastguard Worker.match {$count :number} 1911*912701f9SAndroid Build Coastguard Worker1 {{One new message}} 1912*912701f9SAndroid Build Coastguard Worker* {{{$count :number} new messages}} 1913*912701f9SAndroid Build Coastguard Worker``` 1914*912701f9SAndroid Build Coastguard Worker 1915*912701f9SAndroid Build Coastguard WorkerFurthermore, 1916*912701f9SAndroid Build Coastguard Worker`:number`'s `<matchSignature>` contains two `<match>` elements 1917*912701f9SAndroid Build Coastguard Workerwhich allow the validation of variant keys. 1918*912701f9SAndroid Build Coastguard WorkerThe element whose `locales` best matches the current locale 1919*912701f9SAndroid Build Coastguard Workerusing resource item [lookup](tr35.md#Lookup) from LDML is used. 1920*912701f9SAndroid Build Coastguard WorkerAn element with no `locales` attribute is the default 1921*912701f9SAndroid Build Coastguard Worker(and is considered equivalent to the `root` locale). 1922*912701f9SAndroid Build Coastguard Worker 1923*912701f9SAndroid Build Coastguard Worker- `<match locales="en" values="one two few other" .../>` can be used in locales like `en` and `en-GB` 1924*912701f9SAndroid Build Coastguard Worker to validate the `when other` variant by verifying that the `other` key is present 1925*912701f9SAndroid Build Coastguard Worker in the list of enumarated values: `one other`. 1926*912701f9SAndroid Build Coastguard Worker- `<match ... validationRule="anyNumber"/>` can be used to valide the `when 1` variant 1927*912701f9SAndroid Build Coastguard Worker by testing the `1` key against the `anyNumber` regular expression defined in the registry file. 1928*912701f9SAndroid Build Coastguard Worker 1929*912701f9SAndroid Build Coastguard Worker--- 1930*912701f9SAndroid Build Coastguard Worker 1931*912701f9SAndroid Build Coastguard WorkerA localization engineer can then extend the registry by defining the following `customRegistry.xml` file. 1932*912701f9SAndroid Build Coastguard Worker 1933*912701f9SAndroid Build Coastguard Worker```xml 1934*912701f9SAndroid Build Coastguard Worker<?xml version="1.0" encoding="UTF-8" ?> 1935*912701f9SAndroid Build Coastguard Worker<!DOCTYPE registry SYSTEM "./registry.dtd"> 1936*912701f9SAndroid Build Coastguard Worker 1937*912701f9SAndroid Build Coastguard Worker<registry xml:lang="en"> 1938*912701f9SAndroid Build Coastguard Worker <function name="noun"> 1939*912701f9SAndroid Build Coastguard Worker <description>Handle the grammar of a noun.</description> 1940*912701f9SAndroid Build Coastguard Worker <formatSignature> 1941*912701f9SAndroid Build Coastguard Worker <override locales="en"> 1942*912701f9SAndroid Build Coastguard Worker <input/> 1943*912701f9SAndroid Build Coastguard Worker <option name="article" values="definite indefinite"/> 1944*912701f9SAndroid Build Coastguard Worker <option name="plural" values="one other"/> 1945*912701f9SAndroid Build Coastguard Worker <option name="case" values="nominative genitive" default="nominative"/> 1946*912701f9SAndroid Build Coastguard Worker </override> 1947*912701f9SAndroid Build Coastguard Worker </formatSignature> 1948*912701f9SAndroid Build Coastguard Worker </function> 1949*912701f9SAndroid Build Coastguard Worker 1950*912701f9SAndroid Build Coastguard Worker <function name="adjective"> 1951*912701f9SAndroid Build Coastguard Worker <description>Handle the grammar of an adjective.</description> 1952*912701f9SAndroid Build Coastguard Worker <formatSignature> 1953*912701f9SAndroid Build Coastguard Worker <override locales="en"> 1954*912701f9SAndroid Build Coastguard Worker <input/> 1955*912701f9SAndroid Build Coastguard Worker <option name="article" values="definite indefinite"/> 1956*912701f9SAndroid Build Coastguard Worker <option name="plural" values="one other"/> 1957*912701f9SAndroid Build Coastguard Worker <option name="case" values="nominative genitive" default="nominative"/> 1958*912701f9SAndroid Build Coastguard Worker </override> 1959*912701f9SAndroid Build Coastguard Worker </formatSignature> 1960*912701f9SAndroid Build Coastguard Worker <formatSignature> 1961*912701f9SAndroid Build Coastguard Worker <override locales="en"> 1962*912701f9SAndroid Build Coastguard Worker <input/> 1963*912701f9SAndroid Build Coastguard Worker <option name="article" values="definite indefinite"/> 1964*912701f9SAndroid Build Coastguard Worker <option name="accord"/> 1965*912701f9SAndroid Build Coastguard Worker </override> 1966*912701f9SAndroid Build Coastguard Worker </formatSignature> 1967*912701f9SAndroid Build Coastguard Worker </function> 1968*912701f9SAndroid Build Coastguard Worker</registry> 1969*912701f9SAndroid Build Coastguard Worker``` 1970*912701f9SAndroid Build Coastguard Worker 1971*912701f9SAndroid Build Coastguard WorkerMessages can now use the `:noun` and the `:adjective` functions. 1972*912701f9SAndroid Build Coastguard WorkerThe following message references the first signature of `:adjective`, 1973*912701f9SAndroid Build Coastguard Workerwhich expects the `plural` and `case` options: 1974*912701f9SAndroid Build Coastguard Worker 1975*912701f9SAndroid Build Coastguard Worker> ``` 1976*912701f9SAndroid Build Coastguard Worker> You see {$color :adjective article=indefinite plural=one case=nominative} {$object :noun case=nominative}! 1977*912701f9SAndroid Build Coastguard Worker> ``` 1978*912701f9SAndroid Build Coastguard Worker 1979*912701f9SAndroid Build Coastguard WorkerThe following message references the second signature of `:adjective`, 1980*912701f9SAndroid Build Coastguard Workerwhich only expects the `accord` option: 1981*912701f9SAndroid Build Coastguard Worker 1982*912701f9SAndroid Build Coastguard Worker>``` 1983*912701f9SAndroid Build Coastguard Worker> .input {$object :noun case=nominative} 1984*912701f9SAndroid Build Coastguard Worker> {{You see {$color :adjective article=indefinite accord=$object} {$object}!}} 1985*912701f9SAndroid Build Coastguard Worker>``` 1986*912701f9SAndroid Build Coastguard Worker 1987*912701f9SAndroid Build Coastguard Worker### Default Registry 1988*912701f9SAndroid Build Coastguard Worker 1989*912701f9SAndroid Build Coastguard Worker> [!IMPORTANT] 1990*912701f9SAndroid Build Coastguard Worker> This part of the specification is part of the Tech Preview 1991*912701f9SAndroid Build Coastguard Worker> and is **_NORMATIVE_**. 1992*912701f9SAndroid Build Coastguard Worker 1993*912701f9SAndroid Build Coastguard WorkerThis section describes the functions which each implementation MUST provide 1994*912701f9SAndroid Build Coastguard Workerto be conformant with this specification. 1995*912701f9SAndroid Build Coastguard Worker 1996*912701f9SAndroid Build Coastguard Worker#### String Value Selection and Formatting 1997*912701f9SAndroid Build Coastguard Worker 1998*912701f9SAndroid Build Coastguard Worker##### The `:string` function 1999*912701f9SAndroid Build Coastguard Worker 2000*912701f9SAndroid Build Coastguard WorkerThe function `:string` provides string selection and formatting. 2001*912701f9SAndroid Build Coastguard Worker 2002*912701f9SAndroid Build Coastguard Worker###### Operands 2003*912701f9SAndroid Build Coastguard Worker 2004*912701f9SAndroid Build Coastguard WorkerThe _operand_ of `:string` is either any implementation-defined type 2005*912701f9SAndroid Build Coastguard Workerthat is a string or for which conversion to a string is supported, 2006*912701f9SAndroid Build Coastguard Workeror any _literal_ value. 2007*912701f9SAndroid Build Coastguard WorkerAll other values produce an _Invalid Expression_ error. 2008*912701f9SAndroid Build Coastguard Worker 2009*912701f9SAndroid Build Coastguard Worker> For example, in Java, implementations of the `java.lang.CharSequence` interface 2010*912701f9SAndroid Build Coastguard Worker> (such as `java.lang.String` or `java.lang.StringBuilder`), 2011*912701f9SAndroid Build Coastguard Worker> the type `char`, or the class `java.lang.Character` might be considered 2012*912701f9SAndroid Build Coastguard Worker> as the "implementation-defined types". 2013*912701f9SAndroid Build Coastguard Worker> Such an implementation might also support other classes via the method `toString()`. 2014*912701f9SAndroid Build Coastguard Worker> This might be used to enable selection of a `enum` value by name, for example. 2015*912701f9SAndroid Build Coastguard Worker> 2016*912701f9SAndroid Build Coastguard Worker> Other programming languages would define string and character sequence types or 2017*912701f9SAndroid Build Coastguard Worker> classes according to their local needs, including, where appropriate, 2018*912701f9SAndroid Build Coastguard Worker> coercion to string. 2019*912701f9SAndroid Build Coastguard Worker 2020*912701f9SAndroid Build Coastguard Worker###### Options 2021*912701f9SAndroid Build Coastguard Worker 2022*912701f9SAndroid Build Coastguard WorkerThe function `:string` has no options. 2023*912701f9SAndroid Build Coastguard Worker 2024*912701f9SAndroid Build Coastguard Worker> [!NOTE] 2025*912701f9SAndroid Build Coastguard Worker> Proposals for string transformation options or implementation 2026*912701f9SAndroid Build Coastguard Worker> experience with user requirements is desired during the Tech Preview. 2027*912701f9SAndroid Build Coastguard Worker 2028*912701f9SAndroid Build Coastguard Worker###### Selection 2029*912701f9SAndroid Build Coastguard Worker 2030*912701f9SAndroid Build Coastguard WorkerWhen implementing [`MatchSelectorKeys(resolvedSelector, keys)`](#resolve-preferences) 2031*912701f9SAndroid Build Coastguard Workerwhere `resolvedSelector` is the resolved value of a _selector_ _expression_ 2032*912701f9SAndroid Build Coastguard Workerand `keys` is a list of strings, 2033*912701f9SAndroid Build Coastguard Workerthe `:string` selector performs as described below. 2034*912701f9SAndroid Build Coastguard Worker 2035*912701f9SAndroid Build Coastguard Worker1. Let `compare` be the string value of `resolvedSelector`. 2036*912701f9SAndroid Build Coastguard Worker1. Let `result` be a new empty list of strings. 2037*912701f9SAndroid Build Coastguard Worker1. For each string `key` in `keys`: 2038*912701f9SAndroid Build Coastguard Worker 1. If `key` and `compare` consist of the same sequence of Unicode code points, then 2039*912701f9SAndroid Build Coastguard Worker 1. Append `key` as the last element of the list `result`. 2040*912701f9SAndroid Build Coastguard Worker1. Return `result`. 2041*912701f9SAndroid Build Coastguard Worker 2042*912701f9SAndroid Build Coastguard Worker> [!NOTE] 2043*912701f9SAndroid Build Coastguard Worker> Matching of `key` and `compare` values is sensitive to the sequence of code points 2044*912701f9SAndroid Build Coastguard Worker> in each string. 2045*912701f9SAndroid Build Coastguard Worker> As a result, variations in how text can be encoded can affect the performance of matching. 2046*912701f9SAndroid Build Coastguard Worker> The function `:string` does not perform case folding or Unicode Normalization of string values. 2047*912701f9SAndroid Build Coastguard Worker> Users SHOULD encode _messages_ and their parts (such as _keys_ and _operands_), 2048*912701f9SAndroid Build Coastguard Worker> in Unicode Normalization Form C (NFC) unless there is a very good reason 2049*912701f9SAndroid Build Coastguard Worker> not to. 2050*912701f9SAndroid Build Coastguard Worker> See also: [String Matching](https://www.w3.org/TR/charmod-norm) 2051*912701f9SAndroid Build Coastguard Worker 2052*912701f9SAndroid Build Coastguard Worker> [!NOTE] 2053*912701f9SAndroid Build Coastguard Worker> Unquoted string literals in a _variant_ do not include spaces. 2054*912701f9SAndroid Build Coastguard Worker> If users wish to match strings that include whitespace 2055*912701f9SAndroid Build Coastguard Worker> (including U+3000 `IDEOGRAPHIC SPACE`) 2056*912701f9SAndroid Build Coastguard Worker> to a key, the `key` needs to be quoted. 2057*912701f9SAndroid Build Coastguard Worker> 2058*912701f9SAndroid Build Coastguard Worker> For example: 2059*912701f9SAndroid Build Coastguard Worker> ``` 2060*912701f9SAndroid Build Coastguard Worker> .match {$string :string} 2061*912701f9SAndroid Build Coastguard Worker> | space key | {{Matches the string " space key "}} 2062*912701f9SAndroid Build Coastguard Worker> * {{Matches the string "space key"}} 2063*912701f9SAndroid Build Coastguard Worker> ``` 2064*912701f9SAndroid Build Coastguard Worker 2065*912701f9SAndroid Build Coastguard Worker###### Formatting 2066*912701f9SAndroid Build Coastguard Worker 2067*912701f9SAndroid Build Coastguard WorkerThe `:string` function returns the string value of the resolved value of the _operand_. 2068*912701f9SAndroid Build Coastguard Worker 2069*912701f9SAndroid Build Coastguard Worker#### Numeric Value Selection and Formatting 2070*912701f9SAndroid Build Coastguard Worker 2071*912701f9SAndroid Build Coastguard Worker##### The `:number` function 2072*912701f9SAndroid Build Coastguard Worker 2073*912701f9SAndroid Build Coastguard WorkerThe function `:number` is a selector and formatter for numeric values. 2074*912701f9SAndroid Build Coastguard Worker 2075*912701f9SAndroid Build Coastguard Worker###### Operands 2076*912701f9SAndroid Build Coastguard Worker 2077*912701f9SAndroid Build Coastguard WorkerThe function `:number` requires a [Number Operand](#number-operands) as its _operand_. 2078*912701f9SAndroid Build Coastguard Worker 2079*912701f9SAndroid Build Coastguard Worker###### Options 2080*912701f9SAndroid Build Coastguard Worker 2081*912701f9SAndroid Build Coastguard WorkerSome options do not have default values defined in this specification. 2082*912701f9SAndroid Build Coastguard WorkerThe defaults for these options are implementation-dependent. 2083*912701f9SAndroid Build Coastguard WorkerIn general, the default values for such options depend on the locale, 2084*912701f9SAndroid Build Coastguard Workerthe value of other options, or both. 2085*912701f9SAndroid Build Coastguard Worker 2086*912701f9SAndroid Build Coastguard WorkerThe following options and their values are required to be available on the function `:number`: 2087*912701f9SAndroid Build Coastguard Worker- `select` 2088*912701f9SAndroid Build Coastguard Worker - `plural` (default; see [Default Value of `select` Option](#default-value-of-select-option) below) 2089*912701f9SAndroid Build Coastguard Worker - `ordinal` 2090*912701f9SAndroid Build Coastguard Worker - `exact` 2091*912701f9SAndroid Build Coastguard Worker- `compactDisplay` (this option only has meaning when combined with the option `notation=compact`) 2092*912701f9SAndroid Build Coastguard Worker - `short` (default) 2093*912701f9SAndroid Build Coastguard Worker - `long` 2094*912701f9SAndroid Build Coastguard Worker- `notation` 2095*912701f9SAndroid Build Coastguard Worker - `standard` (default) 2096*912701f9SAndroid Build Coastguard Worker - `scientific` 2097*912701f9SAndroid Build Coastguard Worker - `engineering` 2098*912701f9SAndroid Build Coastguard Worker - `compact` 2099*912701f9SAndroid Build Coastguard Worker- `numberingSystem` 2100*912701f9SAndroid Build Coastguard Worker - valid [Unicode Number System Identifier](https://cldr-smoke.unicode.org/spec/main/ldml/tr35.html#UnicodeNumberSystemIdentifier) 2101*912701f9SAndroid Build Coastguard Worker (default is locale-specific) 2102*912701f9SAndroid Build Coastguard Worker- `signDisplay` 2103*912701f9SAndroid Build Coastguard Worker - `auto` (default) 2104*912701f9SAndroid Build Coastguard Worker - `always` 2105*912701f9SAndroid Build Coastguard Worker - `exceptZero` 2106*912701f9SAndroid Build Coastguard Worker - `negative` 2107*912701f9SAndroid Build Coastguard Worker - `never` 2108*912701f9SAndroid Build Coastguard Worker- `style` 2109*912701f9SAndroid Build Coastguard Worker - `decimal` (default) 2110*912701f9SAndroid Build Coastguard Worker - `percent` (see [Percent Style](#percent-style) below) 2111*912701f9SAndroid Build Coastguard Worker- `useGrouping` 2112*912701f9SAndroid Build Coastguard Worker - `auto` (default) 2113*912701f9SAndroid Build Coastguard Worker - `always` 2114*912701f9SAndroid Build Coastguard Worker - `never` 2115*912701f9SAndroid Build Coastguard Worker - `min2` 2116*912701f9SAndroid Build Coastguard Worker- `minimumIntegerDigits` 2117*912701f9SAndroid Build Coastguard Worker - ([digit size option](#digit-size-options), default: `1`) 2118*912701f9SAndroid Build Coastguard Worker- `minimumFractionDigits` 2119*912701f9SAndroid Build Coastguard Worker - ([digit size option](#digit-size-options)) 2120*912701f9SAndroid Build Coastguard Worker- `maximumFractionDigits` 2121*912701f9SAndroid Build Coastguard Worker - ([digit size option](#digit-size-options)) 2122*912701f9SAndroid Build Coastguard Worker- `minimumSignificantDigits` 2123*912701f9SAndroid Build Coastguard Worker - ([digit size option](#digit-size-options)) 2124*912701f9SAndroid Build Coastguard Worker- `maximumSignificantDigits` 2125*912701f9SAndroid Build Coastguard Worker - ([digit size option](#digit-size-options)) 2126*912701f9SAndroid Build Coastguard Worker 2127*912701f9SAndroid Build Coastguard Worker> [!NOTE] 2128*912701f9SAndroid Build Coastguard Worker> The following options and option values are being developed during the Technical Preview 2129*912701f9SAndroid Build Coastguard Worker> period. 2130*912701f9SAndroid Build Coastguard Worker 2131*912701f9SAndroid Build Coastguard WorkerThe following values for the option `style` are _not_ part of the default registry. 2132*912701f9SAndroid Build Coastguard WorkerImplementations SHOULD avoid creating options that conflict with these, but 2133*912701f9SAndroid Build Coastguard Workerare encouraged to track development of these options during Tech Preview: 2134*912701f9SAndroid Build Coastguard Worker- `currency` 2135*912701f9SAndroid Build Coastguard Worker- `unit` 2136*912701f9SAndroid Build Coastguard Worker 2137*912701f9SAndroid Build Coastguard WorkerThe following options are _not_ part of the default registry. 2138*912701f9SAndroid Build Coastguard WorkerImplementations SHOULD avoid creating options that conflict with these, but 2139*912701f9SAndroid Build Coastguard Workerare encouraged to track development of these options during Tech Preview: 2140*912701f9SAndroid Build Coastguard Worker- `currency` 2141*912701f9SAndroid Build Coastguard Worker - valid [Unicode Currency Identifier](https://cldr-smoke.unicode.org/spec/main/ldml/tr35.html#UnicodeCurrencyIdentifier) 2142*912701f9SAndroid Build Coastguard Worker (no default) 2143*912701f9SAndroid Build Coastguard Worker- `currencyDisplay` 2144*912701f9SAndroid Build Coastguard Worker - `symbol` (default) 2145*912701f9SAndroid Build Coastguard Worker - `narrowSymbol` 2146*912701f9SAndroid Build Coastguard Worker - `code` 2147*912701f9SAndroid Build Coastguard Worker - `name` 2148*912701f9SAndroid Build Coastguard Worker- `currencySign` 2149*912701f9SAndroid Build Coastguard Worker - `accounting` 2150*912701f9SAndroid Build Coastguard Worker - `standard` (default) 2151*912701f9SAndroid Build Coastguard Worker- `unit` 2152*912701f9SAndroid Build Coastguard Worker - (anything not empty) 2153*912701f9SAndroid Build Coastguard Worker- `unitDisplay` 2154*912701f9SAndroid Build Coastguard Worker - `long` 2155*912701f9SAndroid Build Coastguard Worker - `short` (default) 2156*912701f9SAndroid Build Coastguard Worker - `narrow` 2157*912701f9SAndroid Build Coastguard Worker 2158*912701f9SAndroid Build Coastguard Worker###### Default Value of `select` Option 2159*912701f9SAndroid Build Coastguard Worker 2160*912701f9SAndroid Build Coastguard WorkerThe value `plural` is the default for the option `select` 2161*912701f9SAndroid Build Coastguard Workerbecause it is the most common use case for numeric selection. 2162*912701f9SAndroid Build Coastguard WorkerIt can be used for exact value matches but also allows for the grammatical needs of 2163*912701f9SAndroid Build Coastguard Workerlanguages using CLDR's plural rules. 2164*912701f9SAndroid Build Coastguard WorkerThis might not be noticeable in the source language (particularly English), 2165*912701f9SAndroid Build Coastguard Workerbut can cause problems in target locales that the original developer is not considering. 2166*912701f9SAndroid Build Coastguard Worker 2167*912701f9SAndroid Build Coastguard Worker> For example, a naive developer might use a special message for the value `1` without 2168*912701f9SAndroid Build Coastguard Worker> considering a locale's need for a `one` plural: 2169*912701f9SAndroid Build Coastguard Worker> ``` 2170*912701f9SAndroid Build Coastguard Worker> .match {$var :number} 2171*912701f9SAndroid Build Coastguard Worker> 1 {{You have one last chance}} 2172*912701f9SAndroid Build Coastguard Worker> one {{You have {$var} chance remaining}} 2173*912701f9SAndroid Build Coastguard Worker> * {{You have {$var} chances remaining}} 2174*912701f9SAndroid Build Coastguard Worker> ``` 2175*912701f9SAndroid Build Coastguard Worker> 2176*912701f9SAndroid Build Coastguard Worker> The `one` variant is needed by languages such as Polish or Russian. 2177*912701f9SAndroid Build Coastguard Worker> Such locales typically also require other keywords such as `two`, `few`, and `many`. 2178*912701f9SAndroid Build Coastguard Worker 2179*912701f9SAndroid Build Coastguard Worker###### Percent Style 2180*912701f9SAndroid Build Coastguard WorkerWhen implementing `style=percent`, the numeric value of the _operand_ 2181*912701f9SAndroid Build Coastguard WorkerMUST be multiplied by 100 for the purposes of formatting. 2182*912701f9SAndroid Build Coastguard Worker 2183*912701f9SAndroid Build Coastguard Worker> For example, 2184*912701f9SAndroid Build Coastguard Worker> ``` 2185*912701f9SAndroid Build Coastguard Worker> The total was {0.5 :number style=percent}. 2186*912701f9SAndroid Build Coastguard Worker> ``` 2187*912701f9SAndroid Build Coastguard Worker> should format in a manner similar to: 2188*912701f9SAndroid Build Coastguard Worker> > The total was 50%. 2189*912701f9SAndroid Build Coastguard Worker 2190*912701f9SAndroid Build Coastguard Worker###### Selection 2191*912701f9SAndroid Build Coastguard Worker 2192*912701f9SAndroid Build Coastguard WorkerThe _function_ `:number` performs selection as described in [Number Selection](#number-selection) below. 2193*912701f9SAndroid Build Coastguard Worker 2194*912701f9SAndroid Build Coastguard Worker##### The `:integer` function 2195*912701f9SAndroid Build Coastguard Worker 2196*912701f9SAndroid Build Coastguard WorkerThe function `:integer` is a selector and formatter for matching or formatting numeric 2197*912701f9SAndroid Build Coastguard Workervalues as integers. 2198*912701f9SAndroid Build Coastguard Worker 2199*912701f9SAndroid Build Coastguard Worker###### Operands 2200*912701f9SAndroid Build Coastguard Worker 2201*912701f9SAndroid Build Coastguard WorkerThe function `:integer` requires a [Number Operand](#number-operands) as its _operand_. 2202*912701f9SAndroid Build Coastguard Worker 2203*912701f9SAndroid Build Coastguard Worker 2204*912701f9SAndroid Build Coastguard Worker###### Options 2205*912701f9SAndroid Build Coastguard Worker 2206*912701f9SAndroid Build Coastguard WorkerSome options do not have default values defined in this specification. 2207*912701f9SAndroid Build Coastguard WorkerThe defaults for these options are implementation-dependent. 2208*912701f9SAndroid Build Coastguard WorkerIn general, the default values for such options depend on the locale, 2209*912701f9SAndroid Build Coastguard Workerthe value of other options, or both. 2210*912701f9SAndroid Build Coastguard Worker 2211*912701f9SAndroid Build Coastguard WorkerThe following options and their values are required in the default registry to be available on the 2212*912701f9SAndroid Build Coastguard Workerfunction `:integer`: 2213*912701f9SAndroid Build Coastguard Worker- `select` 2214*912701f9SAndroid Build Coastguard Worker - `plural` (default) 2215*912701f9SAndroid Build Coastguard Worker - `ordinal` 2216*912701f9SAndroid Build Coastguard Worker - `exact` 2217*912701f9SAndroid Build Coastguard Worker- `numberingSystem` 2218*912701f9SAndroid Build Coastguard Worker - valid [Unicode Number System Identifier](https://cldr-smoke.unicode.org/spec/main/ldml/tr35.html#UnicodeNumberSystemIdentifier) 2219*912701f9SAndroid Build Coastguard Worker (default is locale-specific) 2220*912701f9SAndroid Build Coastguard Worker- `signDisplay` 2221*912701f9SAndroid Build Coastguard Worker - `auto` (default) 2222*912701f9SAndroid Build Coastguard Worker - `always` 2223*912701f9SAndroid Build Coastguard Worker - `exceptZero` 2224*912701f9SAndroid Build Coastguard Worker - `negative` 2225*912701f9SAndroid Build Coastguard Worker - `never` 2226*912701f9SAndroid Build Coastguard Worker- `style` 2227*912701f9SAndroid Build Coastguard Worker - `decimal` (default) 2228*912701f9SAndroid Build Coastguard Worker - `percent` (see [Percent Style](#percent-style) below) 2229*912701f9SAndroid Build Coastguard Worker- `useGrouping` 2230*912701f9SAndroid Build Coastguard Worker - `auto` (default) 2231*912701f9SAndroid Build Coastguard Worker - `always` 2232*912701f9SAndroid Build Coastguard Worker - `min2` 2233*912701f9SAndroid Build Coastguard Worker- `minimumIntegerDigits` 2234*912701f9SAndroid Build Coastguard Worker - ([digit size option](#digit-size-options), default: `1`) 2235*912701f9SAndroid Build Coastguard Worker- `maximumSignificantDigits` 2236*912701f9SAndroid Build Coastguard Worker - ([digit size option](#digit-size-options)) 2237*912701f9SAndroid Build Coastguard Worker 2238*912701f9SAndroid Build Coastguard Worker> [!NOTE] 2239*912701f9SAndroid Build Coastguard Worker> The following options and option values are being developed during the Technical Preview 2240*912701f9SAndroid Build Coastguard Worker> period. 2241*912701f9SAndroid Build Coastguard Worker 2242*912701f9SAndroid Build Coastguard WorkerThe following values for the option `style` are _not_ part of the default registry. 2243*912701f9SAndroid Build Coastguard WorkerImplementations SHOULD avoid creating options that conflict with these, but 2244*912701f9SAndroid Build Coastguard Workerare encouraged to track development of these options during Tech Preview: 2245*912701f9SAndroid Build Coastguard Worker- `currency` 2246*912701f9SAndroid Build Coastguard Worker- `unit` 2247*912701f9SAndroid Build Coastguard Worker 2248*912701f9SAndroid Build Coastguard WorkerThe following options are _not_ part of the default registry. 2249*912701f9SAndroid Build Coastguard WorkerImplementations SHOULD avoid creating options that conflict with these, but 2250*912701f9SAndroid Build Coastguard Workerare encouraged to track development of these options during Tech Preview: 2251*912701f9SAndroid Build Coastguard Worker- `currency` 2252*912701f9SAndroid Build Coastguard Worker - valid [Unicode Currency Identifier](https://cldr-smoke.unicode.org/spec/main/ldml/tr35.html#UnicodeCurrencyIdentifier) 2253*912701f9SAndroid Build Coastguard Worker (no default) 2254*912701f9SAndroid Build Coastguard Worker- `currencyDisplay` 2255*912701f9SAndroid Build Coastguard Worker - `symbol` (default) 2256*912701f9SAndroid Build Coastguard Worker - `narrowSymbol` 2257*912701f9SAndroid Build Coastguard Worker - `code` 2258*912701f9SAndroid Build Coastguard Worker - `name` 2259*912701f9SAndroid Build Coastguard Worker- `currencySign` 2260*912701f9SAndroid Build Coastguard Worker - `accounting` 2261*912701f9SAndroid Build Coastguard Worker - `standard` (default) 2262*912701f9SAndroid Build Coastguard Worker- `unit` 2263*912701f9SAndroid Build Coastguard Worker - (anything not empty) 2264*912701f9SAndroid Build Coastguard Worker- `unitDisplay` 2265*912701f9SAndroid Build Coastguard Worker - `long` 2266*912701f9SAndroid Build Coastguard Worker - `short` (default) 2267*912701f9SAndroid Build Coastguard Worker - `narrow` 2268*912701f9SAndroid Build Coastguard Worker 2269*912701f9SAndroid Build Coastguard Worker###### Default Value of `select` Option 2270*912701f9SAndroid Build Coastguard Worker 2271*912701f9SAndroid Build Coastguard WorkerThe value `plural` is the default for the option `select` 2272*912701f9SAndroid Build Coastguard Workerbecause it is the most common use case for numeric selection. 2273*912701f9SAndroid Build Coastguard WorkerIt can be used for exact value matches but also allows for the grammatical needs of 2274*912701f9SAndroid Build Coastguard Workerlanguages using CLDR's plural rules. 2275*912701f9SAndroid Build Coastguard WorkerThis might not be noticeable in the source language (particularly English), 2276*912701f9SAndroid Build Coastguard Workerbut can cause problems in target locales that the original developer is not considering. 2277*912701f9SAndroid Build Coastguard Worker 2278*912701f9SAndroid Build Coastguard Worker> For example, a naive developer might use a special message for the value `1` without 2279*912701f9SAndroid Build Coastguard Worker> considering a locale's need for a `one` plural: 2280*912701f9SAndroid Build Coastguard Worker> ``` 2281*912701f9SAndroid Build Coastguard Worker> .match {$var :integer} 2282*912701f9SAndroid Build Coastguard Worker> 1 {{You have one last chance}} 2283*912701f9SAndroid Build Coastguard Worker> one {{You have {$var} chance remaining}} 2284*912701f9SAndroid Build Coastguard Worker> * {{You have {$var} chances remaining}} 2285*912701f9SAndroid Build Coastguard Worker> ``` 2286*912701f9SAndroid Build Coastguard Worker> 2287*912701f9SAndroid Build Coastguard Worker> The `one` variant is needed by languages such as Polish or Russian. 2288*912701f9SAndroid Build Coastguard Worker> Such locales typically also require other keywords such as `two`, `few`, and `many`. 2289*912701f9SAndroid Build Coastguard Worker 2290*912701f9SAndroid Build Coastguard Worker###### Percent Style 2291*912701f9SAndroid Build Coastguard WorkerWhen implementing `style=percent`, the numeric value of the _operand_ 2292*912701f9SAndroid Build Coastguard WorkerMUST be multiplied by 100 for the purposes of formatting. 2293*912701f9SAndroid Build Coastguard Worker 2294*912701f9SAndroid Build Coastguard Worker> For example, 2295*912701f9SAndroid Build Coastguard Worker> ``` 2296*912701f9SAndroid Build Coastguard Worker> The total was {0.5 :number style=percent}. 2297*912701f9SAndroid Build Coastguard Worker> ``` 2298*912701f9SAndroid Build Coastguard Worker> should format in a manner similar to: 2299*912701f9SAndroid Build Coastguard Worker> > The total was 50%. 2300*912701f9SAndroid Build Coastguard Worker 2301*912701f9SAndroid Build Coastguard Worker###### Selection 2302*912701f9SAndroid Build Coastguard Worker 2303*912701f9SAndroid Build Coastguard WorkerThe _function_ `:integer` performs selection as described in [Number Selection](#number-selection) below. 2304*912701f9SAndroid Build Coastguard Worker 2305*912701f9SAndroid Build Coastguard Worker##### Number Operands 2306*912701f9SAndroid Build Coastguard Worker 2307*912701f9SAndroid Build Coastguard WorkerThe _operand_ of a number function is either an implementation-defined type or 2308*912701f9SAndroid Build Coastguard Workera literal whose contents match the `number-literal` production in the [ABNF](#complete-abnf). 2309*912701f9SAndroid Build Coastguard WorkerAll other values produce an _Invalid Expression_ error. 2310*912701f9SAndroid Build Coastguard Worker 2311*912701f9SAndroid Build Coastguard Worker> For example, in Java, any subclass of `java.lang.Number` plus the primitive 2312*912701f9SAndroid Build Coastguard Worker> types (`byte`, `short`, `int`, `long`, `float`, `double`, etc.) 2313*912701f9SAndroid Build Coastguard Worker> might be considered as the "implementation-defined numeric types". 2314*912701f9SAndroid Build Coastguard Worker> Implementations in other programming languages would define different types 2315*912701f9SAndroid Build Coastguard Worker> or classes according to their local needs. 2316*912701f9SAndroid Build Coastguard Worker 2317*912701f9SAndroid Build Coastguard Worker> [!NOTE] 2318*912701f9SAndroid Build Coastguard Worker> String values passed as variables in the _formatting context_'s 2319*912701f9SAndroid Build Coastguard Worker> _input mapping_ can be formatted as numeric values as long as their 2320*912701f9SAndroid Build Coastguard Worker> contents match the `number-literal` production in the [ABNF](#complete-abnf). 2321*912701f9SAndroid Build Coastguard Worker> 2322*912701f9SAndroid Build Coastguard Worker> For example, if the value of the variable `num` were the string 2323*912701f9SAndroid Build Coastguard Worker> `-1234.567`, it would behave identically to the local 2324*912701f9SAndroid Build Coastguard Worker> variable in this example: 2325*912701f9SAndroid Build Coastguard Worker> ``` 2326*912701f9SAndroid Build Coastguard Worker> .local $example = {|-1234.567| :number} 2327*912701f9SAndroid Build Coastguard Worker> {{{$num :number} == {$example}}} 2328*912701f9SAndroid Build Coastguard Worker> ``` 2329*912701f9SAndroid Build Coastguard Worker 2330*912701f9SAndroid Build Coastguard Worker> [!NOTE] 2331*912701f9SAndroid Build Coastguard Worker> Implementations are encouraged to provide support for compound types or data structures 2332*912701f9SAndroid Build Coastguard Worker> that provide additional semantic meaning to the formatting of number-like values. 2333*912701f9SAndroid Build Coastguard Worker> For example, in ICU4J, the type `com.ibm.icu.util.Measure` can be used to communicate 2334*912701f9SAndroid Build Coastguard Worker> a value that includes a unit 2335*912701f9SAndroid Build Coastguard Worker> or the type `com.ibm.icu.util.CurrencyAmount` can be used to set the currency and related 2336*912701f9SAndroid Build Coastguard Worker> options (such as the number of fraction digits). 2337*912701f9SAndroid Build Coastguard Worker 2338*912701f9SAndroid Build Coastguard Worker##### Digit Size Options 2339*912701f9SAndroid Build Coastguard Worker 2340*912701f9SAndroid Build Coastguard WorkerSome _options_ of number _functions_ are defined to take a "digit size option". 2341*912701f9SAndroid Build Coastguard WorkerImplementations of number _functions_ use these _options_ to control aspects of numeric display 2342*912701f9SAndroid Build Coastguard Workersuch as the number of fraction, integer, or significant digits. 2343*912701f9SAndroid Build Coastguard Worker 2344*912701f9SAndroid Build Coastguard WorkerA "digit size option" is an _option_ value that the _function_ interprets 2345*912701f9SAndroid Build Coastguard Workeras a small integer value greater than or equal to zero. 2346*912701f9SAndroid Build Coastguard WorkerImplementations MAY define an upper limit on the resolved value 2347*912701f9SAndroid Build Coastguard Workerof a digit size option option consistent with that implementation's practical limits. 2348*912701f9SAndroid Build Coastguard Worker 2349*912701f9SAndroid Build Coastguard WorkerIn most cases, the value of a digit size option will be a string that 2350*912701f9SAndroid Build Coastguard Workerencodes the value as a decimal integer. 2351*912701f9SAndroid Build Coastguard WorkerImplementations MAY also accept implementation-defined types as the value. 2352*912701f9SAndroid Build Coastguard WorkerWhen provided as a string, the representation of a digit size option matches the following ABNF: 2353*912701f9SAndroid Build Coastguard Worker>```abnf 2354*912701f9SAndroid Build Coastguard Worker> digit-size-option = "0" / (("1"-"9") [DIGIT]) 2355*912701f9SAndroid Build Coastguard Worker>``` 2356*912701f9SAndroid Build Coastguard Worker 2357*912701f9SAndroid Build Coastguard Worker 2358*912701f9SAndroid Build Coastguard Worker##### Number Selection 2359*912701f9SAndroid Build Coastguard Worker 2360*912701f9SAndroid Build Coastguard WorkerNumber selection has three modes: 2361*912701f9SAndroid Build Coastguard Worker- `exact` selection matches the operand to explicit numeric keys exactly 2362*912701f9SAndroid Build Coastguard Worker- `plural` selection matches the operand to explicit numeric keys exactly 2363*912701f9SAndroid Build Coastguard Worker or to plural rule categories if there is no explicit match 2364*912701f9SAndroid Build Coastguard Worker- `ordinal` selection matches the operand to explicit numeric keys exactly 2365*912701f9SAndroid Build Coastguard Worker or to ordinal rule categories if there is no explicit match 2366*912701f9SAndroid Build Coastguard Worker 2367*912701f9SAndroid Build Coastguard WorkerWhen implementing [`MatchSelectorKeys(resolvedSelector, keys)`](#resolve-preferences) 2368*912701f9SAndroid Build Coastguard Workerwhere `resolvedSelector` is the resolved value of a _selector_ _expression_ 2369*912701f9SAndroid Build Coastguard Workerand `keys` is a list of strings, 2370*912701f9SAndroid Build Coastguard Workernumeric selectors perform as described below. 2371*912701f9SAndroid Build Coastguard Worker 2372*912701f9SAndroid Build Coastguard Worker1. Let `exact` be the JSON string representation of the numeric value of `resolvedSelector`. 2373*912701f9SAndroid Build Coastguard Worker (See [Determining Exact Literal Match](#determining-exact-literal-match) for details) 2374*912701f9SAndroid Build Coastguard Worker1. Let `keyword` be a string which is the result of [rule selection](#rule-selection) on `resolvedSelector`. 2375*912701f9SAndroid Build Coastguard Worker1. Let `resultExact` be a new empty list of strings. 2376*912701f9SAndroid Build Coastguard Worker1. Let `resultKeyword` be a new empty list of strings. 2377*912701f9SAndroid Build Coastguard Worker1. For each string `key` in `keys`: 2378*912701f9SAndroid Build Coastguard Worker 1. If the value of `key` matches the production `number-literal`, then 2379*912701f9SAndroid Build Coastguard Worker 1. If `key` and `exact` consist of the same sequence of Unicode code points, then 2380*912701f9SAndroid Build Coastguard Worker 1. Append `key` as the last element of the list `resultExact`. 2381*912701f9SAndroid Build Coastguard Worker 1. Else if `key` is one of the keywords `zero`, `one`, `two`, `few`, `many`, or `other`, then 2382*912701f9SAndroid Build Coastguard Worker 1. If `key` and `keyword` consist of the same sequence of Unicode code points, then 2383*912701f9SAndroid Build Coastguard Worker 1. Append `key` as the last element of the list `resultKeyword`. 2384*912701f9SAndroid Build Coastguard Worker 1. Else, emit a _Selection Error_. 2385*912701f9SAndroid Build Coastguard Worker1. Return a new list whose elements are the concatenation of the elements (in order) of `resultExact` followed by the elements (in order) of `resultKeyword`. 2386*912701f9SAndroid Build Coastguard Worker 2387*912701f9SAndroid Build Coastguard Worker> [!NOTE] 2388*912701f9SAndroid Build Coastguard Worker> Implementations are not required to implement this exactly as written. 2389*912701f9SAndroid Build Coastguard Worker> However, the observed behavior must be consistent with what is described here. 2390*912701f9SAndroid Build Coastguard Worker 2391*912701f9SAndroid Build Coastguard Worker###### Rule Selection 2392*912701f9SAndroid Build Coastguard Worker 2393*912701f9SAndroid Build Coastguard WorkerIf the option `select` is set to `exact`, rule-based selection is not used. 2394*912701f9SAndroid Build Coastguard WorkerReturn the empty string. 2395*912701f9SAndroid Build Coastguard Worker 2396*912701f9SAndroid Build Coastguard Worker> [!NOTE] 2397*912701f9SAndroid Build Coastguard Worker> Since valid keys cannot be the empty string in a numeric expression, returning the 2398*912701f9SAndroid Build Coastguard Worker> empty string disables keyword selection. 2399*912701f9SAndroid Build Coastguard Worker 2400*912701f9SAndroid Build Coastguard WorkerIf the option `select` is set to `plural`, selection should be based on CLDR plural rule data 2401*912701f9SAndroid Build Coastguard Workerof type `cardinal`. See [charts](https://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html) 2402*912701f9SAndroid Build Coastguard Workerfor examples. 2403*912701f9SAndroid Build Coastguard Worker 2404*912701f9SAndroid Build Coastguard WorkerIf the option `select` is set to `ordinal`, selection should be based on CLDR plural rule data 2405*912701f9SAndroid Build Coastguard Workerof type `ordinal`. See [charts](https://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html) 2406*912701f9SAndroid Build Coastguard Workerfor examples. 2407*912701f9SAndroid Build Coastguard Worker 2408*912701f9SAndroid Build Coastguard WorkerApply the rules defined by CLDR to the resolved value of the operand and the function options, 2409*912701f9SAndroid Build Coastguard Workerand return the resulting keyword. 2410*912701f9SAndroid Build Coastguard WorkerIf no rules match, return `other`. 2411*912701f9SAndroid Build Coastguard Worker 2412*912701f9SAndroid Build Coastguard Worker> **Example.** 2413*912701f9SAndroid Build Coastguard Worker> In CLDR 44, the Czech (`cs`) plural rule set can be found 2414*912701f9SAndroid Build Coastguard Worker> [here](https://www.unicode.org/cldr/charts/44/supplemental/language_plural_rules.html#cs). 2415*912701f9SAndroid Build Coastguard Worker> 2416*912701f9SAndroid Build Coastguard Worker> A message in Czech might be: 2417*912701f9SAndroid Build Coastguard Worker> ``` 2418*912701f9SAndroid Build Coastguard Worker> .match {$numDays :number} 2419*912701f9SAndroid Build Coastguard Worker> one {{{$numDays} den}} 2420*912701f9SAndroid Build Coastguard Worker> few {{{$numDays} dny}} 2421*912701f9SAndroid Build Coastguard Worker> many {{{$numDays} dne}} 2422*912701f9SAndroid Build Coastguard Worker> * {{{$numDays} dní}} 2423*912701f9SAndroid Build Coastguard Worker> ``` 2424*912701f9SAndroid Build Coastguard Worker> Using the rules found above, the results of various _operand_ values might look like: 2425*912701f9SAndroid Build Coastguard Worker> | Operand value | Keyword | Formatted Message | 2426*912701f9SAndroid Build Coastguard Worker> |---|---|---| 2427*912701f9SAndroid Build Coastguard Worker> | 1 | `one` | 1 den | 2428*912701f9SAndroid Build Coastguard Worker> | 2 | `few` | 2 dny | 2429*912701f9SAndroid Build Coastguard Worker> | 5 | `other` | 5 dní | 2430*912701f9SAndroid Build Coastguard Worker> | 22 | `few` | 22 dny | 2431*912701f9SAndroid Build Coastguard Worker> | 27 | `other` | 27 dní | 2432*912701f9SAndroid Build Coastguard Worker> | 2.4 | `many` | 2,4 dne | 2433*912701f9SAndroid Build Coastguard Worker 2434*912701f9SAndroid Build Coastguard Worker###### Determining Exact Literal Match 2435*912701f9SAndroid Build Coastguard Worker 2436*912701f9SAndroid Build Coastguard Worker> [!IMPORTANT] 2437*912701f9SAndroid Build Coastguard Worker> The exact behavior of exact literal match is only defined for non-zero-filled 2438*912701f9SAndroid Build Coastguard Worker> integer values. 2439*912701f9SAndroid Build Coastguard Worker> Annotations that use fraction digits or significant digits might work in specific 2440*912701f9SAndroid Build Coastguard Worker> implementation-defined ways. 2441*912701f9SAndroid Build Coastguard Worker> Users should avoid depending on these types of keys in message selection. 2442*912701f9SAndroid Build Coastguard Worker 2443*912701f9SAndroid Build Coastguard Worker 2444*912701f9SAndroid Build Coastguard WorkerNumber literals in the MessageFormat 2 syntax use the 2445*912701f9SAndroid Build Coastguard Worker[format defined for a JSON number](https://www.rfc-editor.org/rfc/rfc8259#section-6). 2446*912701f9SAndroid Build Coastguard WorkerA `resolvedSelector` exactly matches a numeric literal `key` 2447*912701f9SAndroid Build Coastguard Workerif, when the numeric value of `resolvedSelector` is serialized using the format for a JSON number, 2448*912701f9SAndroid Build Coastguard Workerthe two strings are equal. 2449*912701f9SAndroid Build Coastguard Worker 2450*912701f9SAndroid Build Coastguard Worker> [!NOTE] 2451*912701f9SAndroid Build Coastguard Worker> Only integer matching is required in the Technical Preview. 2452*912701f9SAndroid Build Coastguard Worker> Feedback describing use cases for fractional and significant digits-based 2453*912701f9SAndroid Build Coastguard Worker> selection would be helpful. 2454*912701f9SAndroid Build Coastguard Worker> Otherwise, users should avoid using matching with fractional numbers or significant digits. 2455*912701f9SAndroid Build Coastguard Worker 2456*912701f9SAndroid Build Coastguard Worker#### Date and Time Value Formatting 2457*912701f9SAndroid Build Coastguard Worker 2458*912701f9SAndroid Build Coastguard WorkerThis subsection describes the functions and options for date/time formatting. 2459*912701f9SAndroid Build Coastguard WorkerSelection based on date and time values is not required in this release. 2460*912701f9SAndroid Build Coastguard Worker 2461*912701f9SAndroid Build Coastguard Worker> [!NOTE] 2462*912701f9SAndroid Build Coastguard Worker> Selection based on date/time types is not required by MF2. 2463*912701f9SAndroid Build Coastguard Worker> Implementations should use care when defining selectors based on date/time types. 2464*912701f9SAndroid Build Coastguard Worker> The types of queries found in implementations such as `java.time.TemporalAccessor` 2465*912701f9SAndroid Build Coastguard Worker> are complex and user expectations may be inconsistent with good I18N practices. 2466*912701f9SAndroid Build Coastguard Worker 2467*912701f9SAndroid Build Coastguard Worker##### The `:datetime` function 2468*912701f9SAndroid Build Coastguard Worker 2469*912701f9SAndroid Build Coastguard WorkerThe function `:datetime` is used to format date/time values, including 2470*912701f9SAndroid Build Coastguard Workerthe ability to compose user-specified combinations of fields. 2471*912701f9SAndroid Build Coastguard Worker 2472*912701f9SAndroid Build Coastguard WorkerIf no options are specified, this function defaults to the following: 2473*912701f9SAndroid Build Coastguard Worker- `{$d :datetime}` is the same as `{$d :datetime dateStyle=short timeStyle=short}` 2474*912701f9SAndroid Build Coastguard Worker 2475*912701f9SAndroid Build Coastguard Worker> [!NOTE] 2476*912701f9SAndroid Build Coastguard Worker> The default formatting behavior of `:datetime` is inconsistent with `Intl.DateTimeFormat` 2477*912701f9SAndroid Build Coastguard Worker> in JavaScript and with `{d,date}` in ICU MessageFormat 1.0. 2478*912701f9SAndroid Build Coastguard Worker> This is because, unlike those implementations, `:datetime` is distinct from `:date` and `:time`. 2479*912701f9SAndroid Build Coastguard Worker 2480*912701f9SAndroid Build Coastguard Worker###### Operands 2481*912701f9SAndroid Build Coastguard Worker 2482*912701f9SAndroid Build Coastguard WorkerThe _operand_ of the `:datetime` function is either 2483*912701f9SAndroid Build Coastguard Workeran implementation-defined date/time type 2484*912701f9SAndroid Build Coastguard Workeror a _date/time literal value_, as defined in [Date and Time Operand](#date-and-time-operands). 2485*912701f9SAndroid Build Coastguard WorkerAll other _operand_ values produce an _Invalid Expression_ error. 2486*912701f9SAndroid Build Coastguard Worker 2487*912701f9SAndroid Build Coastguard Worker###### Options 2488*912701f9SAndroid Build Coastguard Worker 2489*912701f9SAndroid Build Coastguard WorkerThe `:datetime` function can use either the appropriate _style options_ 2490*912701f9SAndroid Build Coastguard Workeror can use a collection of _field options_ (but not both) to control the formatted 2491*912701f9SAndroid Build Coastguard Workeroutput. 2492*912701f9SAndroid Build Coastguard Worker 2493*912701f9SAndroid Build Coastguard WorkerIf both are specified, an _Invalid Expression_ error MUST be emitted 2494*912701f9SAndroid Build Coastguard Workerand a _fallback value_ used as the resolved value of the _expression_. 2495*912701f9SAndroid Build Coastguard Worker 2496*912701f9SAndroid Build Coastguard Worker**Style Options** 2497*912701f9SAndroid Build Coastguard Worker 2498*912701f9SAndroid Build Coastguard WorkerThe function `:datetime` has these _style options_. 2499*912701f9SAndroid Build Coastguard Worker- `dateStyle` 2500*912701f9SAndroid Build Coastguard Worker - `full` 2501*912701f9SAndroid Build Coastguard Worker - `long` 2502*912701f9SAndroid Build Coastguard Worker - `medium` 2503*912701f9SAndroid Build Coastguard Worker - `short` 2504*912701f9SAndroid Build Coastguard Worker- `timeStyle` 2505*912701f9SAndroid Build Coastguard Worker - `full` 2506*912701f9SAndroid Build Coastguard Worker - `long` 2507*912701f9SAndroid Build Coastguard Worker - `medium` 2508*912701f9SAndroid Build Coastguard Worker - `short` 2509*912701f9SAndroid Build Coastguard Worker 2510*912701f9SAndroid Build Coastguard Worker**Field Options** 2511*912701f9SAndroid Build Coastguard Worker 2512*912701f9SAndroid Build Coastguard Worker_Field options_ describe which fields to include in the formatted output 2513*912701f9SAndroid Build Coastguard Workerand what format to use for that field. 2514*912701f9SAndroid Build Coastguard WorkerThe implementation may use this _annotation_ to configure which fields 2515*912701f9SAndroid Build Coastguard Workerappear in the formatted output. 2516*912701f9SAndroid Build Coastguard Worker 2517*912701f9SAndroid Build Coastguard Worker> [!NOTE] 2518*912701f9SAndroid Build Coastguard Worker> _Field options_ do not have default values because they are only to be used 2519*912701f9SAndroid Build Coastguard Worker> to compose the formatter. 2520*912701f9SAndroid Build Coastguard Worker 2521*912701f9SAndroid Build Coastguard WorkerThe _field options_ are defined as follows: 2522*912701f9SAndroid Build Coastguard Worker 2523*912701f9SAndroid Build Coastguard Worker> [!IMPORTANT] 2524*912701f9SAndroid Build Coastguard Worker> The value `2-digit` for some _field options_ **must** be quoted 2525*912701f9SAndroid Build Coastguard Worker> in the MessageFormat syntax because it starts with a digit 2526*912701f9SAndroid Build Coastguard Worker> but does not match the `number-literal` production in the ABNF. 2527*912701f9SAndroid Build Coastguard Worker> ``` 2528*912701f9SAndroid Build Coastguard Worker> .local $correct = {$someDate :datetime year=|2-digit|} 2529*912701f9SAndroid Build Coastguard Worker> .local $syntaxError = {$someDate :datetime year=2-digit} 2530*912701f9SAndroid Build Coastguard Worker> ``` 2531*912701f9SAndroid Build Coastguard Worker 2532*912701f9SAndroid Build Coastguard WorkerThe function `:datetime` has the following options: 2533*912701f9SAndroid Build Coastguard Worker- `weekday` 2534*912701f9SAndroid Build Coastguard Worker - `long` 2535*912701f9SAndroid Build Coastguard Worker - `short` 2536*912701f9SAndroid Build Coastguard Worker - `narrow` 2537*912701f9SAndroid Build Coastguard Worker- `era` 2538*912701f9SAndroid Build Coastguard Worker - `long` 2539*912701f9SAndroid Build Coastguard Worker - `short` 2540*912701f9SAndroid Build Coastguard Worker - `narrow` 2541*912701f9SAndroid Build Coastguard Worker- `year` 2542*912701f9SAndroid Build Coastguard Worker - `numeric` 2543*912701f9SAndroid Build Coastguard Worker - `2-digit` 2544*912701f9SAndroid Build Coastguard Worker- `month` 2545*912701f9SAndroid Build Coastguard Worker - `numeric` 2546*912701f9SAndroid Build Coastguard Worker - `2-digit` 2547*912701f9SAndroid Build Coastguard Worker - `long` 2548*912701f9SAndroid Build Coastguard Worker - `short` 2549*912701f9SAndroid Build Coastguard Worker - `narrow` 2550*912701f9SAndroid Build Coastguard Worker- `day` 2551*912701f9SAndroid Build Coastguard Worker - `numeric` 2552*912701f9SAndroid Build Coastguard Worker - `2-digit` 2553*912701f9SAndroid Build Coastguard Worker- `hour` 2554*912701f9SAndroid Build Coastguard Worker - `numeric` 2555*912701f9SAndroid Build Coastguard Worker - `2-digit` 2556*912701f9SAndroid Build Coastguard Worker- `minute` 2557*912701f9SAndroid Build Coastguard Worker - `numeric` 2558*912701f9SAndroid Build Coastguard Worker - `2-digit` 2559*912701f9SAndroid Build Coastguard Worker- `second` 2560*912701f9SAndroid Build Coastguard Worker - `numeric` 2561*912701f9SAndroid Build Coastguard Worker - `2-digit` 2562*912701f9SAndroid Build Coastguard Worker- `fractionalSecondDigits` 2563*912701f9SAndroid Build Coastguard Worker - `1` 2564*912701f9SAndroid Build Coastguard Worker - `2` 2565*912701f9SAndroid Build Coastguard Worker - `3` 2566*912701f9SAndroid Build Coastguard Worker- `hourCycle` (default is locale-specific) 2567*912701f9SAndroid Build Coastguard Worker - `h11` 2568*912701f9SAndroid Build Coastguard Worker - `h12` 2569*912701f9SAndroid Build Coastguard Worker - `h23` 2570*912701f9SAndroid Build Coastguard Worker - `h24` 2571*912701f9SAndroid Build Coastguard Worker- `timeZoneName` 2572*912701f9SAndroid Build Coastguard Worker - `long` 2573*912701f9SAndroid Build Coastguard Worker - `short` 2574*912701f9SAndroid Build Coastguard Worker - `shortOffset` 2575*912701f9SAndroid Build Coastguard Worker - `longOffset` 2576*912701f9SAndroid Build Coastguard Worker - `shortGeneric` 2577*912701f9SAndroid Build Coastguard Worker - `longGeneric` 2578*912701f9SAndroid Build Coastguard Worker 2579*912701f9SAndroid Build Coastguard Worker> [!NOTE] 2580*912701f9SAndroid Build Coastguard Worker> The following options do not have default values because they are only to be used 2581*912701f9SAndroid Build Coastguard Worker> as overrides for locale-and-value dependent implementation-defined defaults. 2582*912701f9SAndroid Build Coastguard Worker 2583*912701f9SAndroid Build Coastguard WorkerThe following date/time options are **not** part of the default registry. 2584*912701f9SAndroid Build Coastguard WorkerImplementations SHOULD avoid creating options that conflict with these, but 2585*912701f9SAndroid Build Coastguard Workerare encouraged to track development of these options during Tech Preview: 2586*912701f9SAndroid Build Coastguard Worker- `calendar` (default is locale-specific) 2587*912701f9SAndroid Build Coastguard Worker - valid [Unicode Calendar Identifier](https://cldr-smoke.unicode.org/spec/main/ldml/tr35.html#UnicodeCalendarIdentifier) 2588*912701f9SAndroid Build Coastguard Worker- `numberingSystem` (default is locale-specific) 2589*912701f9SAndroid Build Coastguard Worker - valid [Unicode Number System Identifier](https://cldr-smoke.unicode.org/spec/main/ldml/tr35.html#UnicodeNumberSystemIdentifier) 2590*912701f9SAndroid Build Coastguard Worker- `timeZone` (default is system default time zone or UTC) 2591*912701f9SAndroid Build Coastguard Worker - valid identifier per [BCP175](https://www.rfc-editor.org/rfc/rfc6557) 2592*912701f9SAndroid Build Coastguard Worker 2593*912701f9SAndroid Build Coastguard Worker##### The `:date` function 2594*912701f9SAndroid Build Coastguard Worker 2595*912701f9SAndroid Build Coastguard WorkerThe function `:date` is used to format the date portion of date/time values. 2596*912701f9SAndroid Build Coastguard Worker 2597*912701f9SAndroid Build Coastguard WorkerIf no options are specified, this function defaults to the following: 2598*912701f9SAndroid Build Coastguard Worker- `{$d :date}` is the same as `{$d :date style=short}` 2599*912701f9SAndroid Build Coastguard Worker 2600*912701f9SAndroid Build Coastguard Worker###### Operands 2601*912701f9SAndroid Build Coastguard Worker 2602*912701f9SAndroid Build Coastguard WorkerThe _operand_ of the `:date` function is either 2603*912701f9SAndroid Build Coastguard Workeran implementation-defined date/time type 2604*912701f9SAndroid Build Coastguard Workeror a _date/time literal value_, as defined in [Date and Time Operand](#date-and-time-operands). 2605*912701f9SAndroid Build Coastguard WorkerAll other _operand_ values produce an _Invalid Expression_ error. 2606*912701f9SAndroid Build Coastguard Worker 2607*912701f9SAndroid Build Coastguard Worker###### Options 2608*912701f9SAndroid Build Coastguard Worker 2609*912701f9SAndroid Build Coastguard WorkerThe function `:date` has these _options_: 2610*912701f9SAndroid Build Coastguard Worker- `style` 2611*912701f9SAndroid Build Coastguard Worker - `full` 2612*912701f9SAndroid Build Coastguard Worker - `long` 2613*912701f9SAndroid Build Coastguard Worker - `medium` 2614*912701f9SAndroid Build Coastguard Worker - `short` (default) 2615*912701f9SAndroid Build Coastguard Worker 2616*912701f9SAndroid Build Coastguard Worker##### The `:time` function 2617*912701f9SAndroid Build Coastguard Worker 2618*912701f9SAndroid Build Coastguard WorkerThe function `:time` is used to format the time portion of date/time values. 2619*912701f9SAndroid Build Coastguard Worker 2620*912701f9SAndroid Build Coastguard WorkerIf no options are specified, this function defaults to the following: 2621*912701f9SAndroid Build Coastguard Worker- `{$t :time}` is the same as `{$t :time style=short}` 2622*912701f9SAndroid Build Coastguard Worker 2623*912701f9SAndroid Build Coastguard Worker###### Operands 2624*912701f9SAndroid Build Coastguard Worker 2625*912701f9SAndroid Build Coastguard WorkerThe _operand_ of the `:time` function is either 2626*912701f9SAndroid Build Coastguard Workeran implementation-defined date/time type 2627*912701f9SAndroid Build Coastguard Workeror a _date/time literal value_, as defined in [Date and Time Operand](#date-and-time-operands). 2628*912701f9SAndroid Build Coastguard WorkerAll other _operand_ values produce an _Invalid Expression_ error. 2629*912701f9SAndroid Build Coastguard Worker 2630*912701f9SAndroid Build Coastguard Worker###### Options 2631*912701f9SAndroid Build Coastguard Worker 2632*912701f9SAndroid Build Coastguard WorkerThe function `:time` has these _options_: 2633*912701f9SAndroid Build Coastguard Worker- `style` 2634*912701f9SAndroid Build Coastguard Worker - `full` 2635*912701f9SAndroid Build Coastguard Worker - `long` 2636*912701f9SAndroid Build Coastguard Worker - `medium` 2637*912701f9SAndroid Build Coastguard Worker - `short` (default) 2638*912701f9SAndroid Build Coastguard Worker 2639*912701f9SAndroid Build Coastguard Worker 2640*912701f9SAndroid Build Coastguard Worker##### Date and Time Operands 2641*912701f9SAndroid Build Coastguard Worker 2642*912701f9SAndroid Build Coastguard WorkerThe _operand_ of a date/time function is either 2643*912701f9SAndroid Build Coastguard Workeran implementation-defined date/time type 2644*912701f9SAndroid Build Coastguard Workeror a _date/time literal value_, as defined below. 2645*912701f9SAndroid Build Coastguard WorkerAll other _operand_ values produce an _Invalid Expression_ error. 2646*912701f9SAndroid Build Coastguard Worker 2647*912701f9SAndroid Build Coastguard WorkerA **_<dfn>date/time literal value</dfn>_** is a non-empty string consisting of an ISO 8601 date, 2648*912701f9SAndroid Build Coastguard Workeror an ISO 8601 datetime optionally followed by a timezone offset. 2649*912701f9SAndroid Build Coastguard WorkerAs implementations differ slightly in their parsing of such strings, 2650*912701f9SAndroid Build Coastguard WorkerISO 8601 date and datetime values not matching the following regular expression MAY also be supported. 2651*912701f9SAndroid Build Coastguard WorkerFurthermore, matching this regular expression does not guarantee validity, 2652*912701f9SAndroid Build Coastguard Workergiven the variable number of days in each month. 2653*912701f9SAndroid Build Coastguard Worker 2654*912701f9SAndroid Build Coastguard Worker```regexp 2655*912701f9SAndroid Build Coastguard Worker(?!0000)[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])(T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\.[0-9]{1,3})?(Z|[+-]((0[0-9]|1[0-3]):[0-5][0-9]|14:00))?)? 2656*912701f9SAndroid Build Coastguard Worker``` 2657*912701f9SAndroid Build Coastguard Worker 2658*912701f9SAndroid Build Coastguard WorkerWhen the time is not present, implementations SHOULD use `00:00:00` as the time. 2659*912701f9SAndroid Build Coastguard WorkerWhen the offset is not present, implementations SHOULD use a floating time type 2660*912701f9SAndroid Build Coastguard Worker(such as Java's `java.time.LocalDateTime`) to represent the time value. 2661*912701f9SAndroid Build Coastguard WorkerFor more information, see [Working with Timezones](https://w3c.github.io/timezone). 2662*912701f9SAndroid Build Coastguard Worker 2663*912701f9SAndroid Build Coastguard Worker> [!IMPORTANT] 2664*912701f9SAndroid Build Coastguard Worker> The [ABNF](#complete-abnf) and [syntax](#syntax) of MF2 2665*912701f9SAndroid Build Coastguard Worker> do not formally define date/time literals. 2666*912701f9SAndroid Build Coastguard Worker> This means that a _message_ can be syntactically valid but produce 2667*912701f9SAndroid Build Coastguard Worker> an _Operand Mismatch Error_ at runtime. 2668*912701f9SAndroid Build Coastguard Worker 2669*912701f9SAndroid Build Coastguard Worker> [!NOTE] 2670*912701f9SAndroid Build Coastguard Worker> String values passed as variables in the _formatting context_'s 2671*912701f9SAndroid Build Coastguard Worker> _input mapping_ can be formatted as date/time values as long as their 2672*912701f9SAndroid Build Coastguard Worker> contents are date/time literals. 2673*912701f9SAndroid Build Coastguard Worker> 2674*912701f9SAndroid Build Coastguard Worker> For example, if the value of the variable `now` were the string 2675*912701f9SAndroid Build Coastguard Worker> `2024-02-06T16:40:00Z`, it would behave identically to the local 2676*912701f9SAndroid Build Coastguard Worker> variable in this example: 2677*912701f9SAndroid Build Coastguard Worker> ``` 2678*912701f9SAndroid Build Coastguard Worker> .local $example = {|2024-02-06T16:40:00Z| :datetime} 2679*912701f9SAndroid Build Coastguard Worker> {{{$now :datetime} == {$example}}} 2680*912701f9SAndroid Build Coastguard Worker> ``` 2681*912701f9SAndroid Build Coastguard Worker 2682*912701f9SAndroid Build Coastguard Worker> [!NOTE] 2683*912701f9SAndroid Build Coastguard Worker> True time zone support in serializations is expected to coincide with the adoption 2684*912701f9SAndroid Build Coastguard Worker> of Temporal in JavaScript. 2685*912701f9SAndroid Build Coastguard Worker> The form of these serializations is known and is a de facto standard. 2686*912701f9SAndroid Build Coastguard Worker> Support for these extensions is expected to be required in the post-tech preview. 2687*912701f9SAndroid Build Coastguard Worker> See: https://datatracker.ietf.org/doc/draft-ietf-sedate-datetime-extended/ 2688*912701f9SAndroid Build Coastguard Worker 2689*912701f9SAndroid Build Coastguard Worker 2690*912701f9SAndroid Build Coastguard Worker 2691*912701f9SAndroid Build Coastguard Worker 2692*912701f9SAndroid Build Coastguard Worker## Formatting 2693*912701f9SAndroid Build Coastguard Worker 2694*912701f9SAndroid Build Coastguard WorkerThis section defines the behavior of a MessageFormat 2.0 implementation 2695*912701f9SAndroid Build Coastguard Workerwhen formatting a message for display in a user interface, or for some later processing. 2696*912701f9SAndroid Build Coastguard Worker 2697*912701f9SAndroid Build Coastguard WorkerTo start, we presume that a _message_ has either been parsed from its syntax 2698*912701f9SAndroid Build Coastguard Workeror created from a data model description. 2699*912701f9SAndroid Build Coastguard WorkerIf this construction has encountered any _Syntax Errors_ or _Data Model Errors_, 2700*912701f9SAndroid Build Coastguard Workeran appropriate error MUST be emitted and a _fallback value_ MAY be used as the formatting result. 2701*912701f9SAndroid Build Coastguard Worker 2702*912701f9SAndroid Build Coastguard WorkerFormatting of a _message_ is defined by the following operations: 2703*912701f9SAndroid Build Coastguard Worker 2704*912701f9SAndroid Build Coastguard Worker- **_Expression and Markup Resolution_** determines the value of an _expression_ or _markup_, 2705*912701f9SAndroid Build Coastguard Worker with reference to the current _formatting context_. 2706*912701f9SAndroid Build Coastguard Worker This can include multiple steps, 2707*912701f9SAndroid Build Coastguard Worker such as looking up the value of a variable and calling formatting functions. 2708*912701f9SAndroid Build Coastguard Worker The form of the resolved value is implementation defined and the 2709*912701f9SAndroid Build Coastguard Worker value might not be evaluated or formatted yet. 2710*912701f9SAndroid Build Coastguard Worker However, it needs to be "formattable", i.e. it contains everything required 2711*912701f9SAndroid Build Coastguard Worker by the eventual formatting. 2712*912701f9SAndroid Build Coastguard Worker 2713*912701f9SAndroid Build Coastguard Worker The resolution of _text_ is rather straightforward, 2714*912701f9SAndroid Build Coastguard Worker and is detailed under _literal resolution_. 2715*912701f9SAndroid Build Coastguard Worker 2716*912701f9SAndroid Build Coastguard Worker> [!IMPORTANT] 2717*912701f9SAndroid Build Coastguard Worker> 2718*912701f9SAndroid Build Coastguard Worker> **This specification does not require either eager or lazy _expression resolution_ of _message_ 2719*912701f9SAndroid Build Coastguard Worker> parts; do not construe any requirement in this document as requiring either.** 2720*912701f9SAndroid Build Coastguard Worker> 2721*912701f9SAndroid Build Coastguard Worker> Implementations are not required to evaluate all parts of a _message_ when 2722*912701f9SAndroid Build Coastguard Worker> parsing, processing, or formatting. 2723*912701f9SAndroid Build Coastguard Worker> In particular, an implementation MAY choose not to evaluate or resolve the 2724*912701f9SAndroid Build Coastguard Worker> value of a given _expression_ until it is actually used by a 2725*912701f9SAndroid Build Coastguard Worker> selection or formatting process. 2726*912701f9SAndroid Build Coastguard Worker> However, when an _expression_ is resolved, it MUST behave as if all preceding 2727*912701f9SAndroid Build Coastguard Worker> _declarations_ and _selectors_ affecting _variables_ referenced by that _expression_ 2728*912701f9SAndroid Build Coastguard Worker> have already been evaluated in the order in which the relevant _declarations_ 2729*912701f9SAndroid Build Coastguard Worker> and _selectors_ appear in the _message_. 2730*912701f9SAndroid Build Coastguard Worker 2731*912701f9SAndroid Build Coastguard Worker- **_Pattern Selection_** determines which of a message's _patterns_ is formatted. 2732*912701f9SAndroid Build Coastguard Worker For a message with no _selectors_, this is simple as there is only one _pattern_. 2733*912701f9SAndroid Build Coastguard Worker With _selectors_, this will depend on their resolution. 2734*912701f9SAndroid Build Coastguard Worker 2735*912701f9SAndroid Build Coastguard Worker At the start of _pattern selection_, 2736*912701f9SAndroid Build Coastguard Worker if the _message_ contains any _reserved statements_, 2737*912701f9SAndroid Build Coastguard Worker emit an _Unsupported Statement_ error. 2738*912701f9SAndroid Build Coastguard Worker 2739*912701f9SAndroid Build Coastguard Worker- **_Formatting_** takes the resolved values of the selected _pattern_, 2740*912701f9SAndroid Build Coastguard Worker and produces the formatted result for the _message_. 2741*912701f9SAndroid Build Coastguard Worker Depending on the implementation, this result could be a single concatenated string, 2742*912701f9SAndroid Build Coastguard Worker an array of objects, an attributed string, or some other locally appropriate data type. 2743*912701f9SAndroid Build Coastguard Worker 2744*912701f9SAndroid Build Coastguard WorkerFormatter implementations are not required to expose 2745*912701f9SAndroid Build Coastguard Workerthe _expression resolution_ and _pattern selection_ operations to their users, 2746*912701f9SAndroid Build Coastguard Workeror even use them in their internal processing, 2747*912701f9SAndroid Build Coastguard Workeras long as the final _formatting_ result is made available to users 2748*912701f9SAndroid Build Coastguard Workerand the observable behavior of the formatter matches that described here. 2749*912701f9SAndroid Build Coastguard Worker 2750*912701f9SAndroid Build Coastguard Worker### Formatting Context 2751*912701f9SAndroid Build Coastguard Worker 2752*912701f9SAndroid Build Coastguard WorkerA message's **_formatting context_** represents the data and procedures that are required 2753*912701f9SAndroid Build Coastguard Workerfor the message's _expression resolution_, _pattern selection_ and _formatting_. 2754*912701f9SAndroid Build Coastguard Worker 2755*912701f9SAndroid Build Coastguard WorkerAt a minimum, it includes: 2756*912701f9SAndroid Build Coastguard Worker 2757*912701f9SAndroid Build Coastguard Worker- Information on the current **_locale_**, 2758*912701f9SAndroid Build Coastguard Worker potentially including a fallback chain of locales. 2759*912701f9SAndroid Build Coastguard Worker This will be passed on to formatting functions. 2760*912701f9SAndroid Build Coastguard Worker 2761*912701f9SAndroid Build Coastguard Worker- Information on the base directionality of the _message_ and its _text_ tokens. 2762*912701f9SAndroid Build Coastguard Worker This will be used by strategies for bidirectional isolation, 2763*912701f9SAndroid Build Coastguard Worker and can be used to set the base direction of the _message_ upon display. 2764*912701f9SAndroid Build Coastguard Worker 2765*912701f9SAndroid Build Coastguard Worker- An **_<dfn>input mapping</dfn>_** of string identifiers to values, 2766*912701f9SAndroid Build Coastguard Worker defining variable values that are available during _variable resolution_. 2767*912701f9SAndroid Build Coastguard Worker This is often determined by a user-provided argument of a formatting function call. 2768*912701f9SAndroid Build Coastguard Worker 2769*912701f9SAndroid Build Coastguard Worker- The _function registry_, 2770*912701f9SAndroid Build Coastguard Worker providing the implementations of the functions referred to by message _functions_. 2771*912701f9SAndroid Build Coastguard Worker 2772*912701f9SAndroid Build Coastguard Worker- Optionally, a fallback string to use for the message 2773*912701f9SAndroid Build Coastguard Worker if it contains any _Syntax Errors_ or _Data Model Errors_. 2774*912701f9SAndroid Build Coastguard Worker 2775*912701f9SAndroid Build Coastguard WorkerImplementations MAY include additional fields in their _formatting context_. 2776*912701f9SAndroid Build Coastguard Worker 2777*912701f9SAndroid Build Coastguard Worker### Expression and Markup Resolution 2778*912701f9SAndroid Build Coastguard Worker 2779*912701f9SAndroid Build Coastguard Worker_Expressions_ are used in _declarations_, _selectors_, and _patterns_. 2780*912701f9SAndroid Build Coastguard Worker_Markup_ is only used in _patterns_. 2781*912701f9SAndroid Build Coastguard Worker 2782*912701f9SAndroid Build Coastguard WorkerIn a _declaration_, the resolved value of the _expression_ is bound to a _variable_, 2783*912701f9SAndroid Build Coastguard Workerwhich is available for use by later _expressions_. 2784*912701f9SAndroid Build Coastguard WorkerSince a _variable_ can be referenced in different ways later, 2785*912701f9SAndroid Build Coastguard Workerimplementations SHOULD NOT immediately fully format the value for output. 2786*912701f9SAndroid Build Coastguard Worker 2787*912701f9SAndroid Build Coastguard WorkerIn an _input-declaration_, the _variable_ operand of the _variable-expression_ 2788*912701f9SAndroid Build Coastguard Workeridentifies not only the name of the external input value, 2789*912701f9SAndroid Build Coastguard Workerbut also the _variable_ to which the resolved value of the _variable-expression_ is bound. 2790*912701f9SAndroid Build Coastguard Worker 2791*912701f9SAndroid Build Coastguard WorkerIn _selectors_, the resolved value of an _expression_ is used for _pattern selection_. 2792*912701f9SAndroid Build Coastguard Worker 2793*912701f9SAndroid Build Coastguard WorkerIn a _pattern_, the resolved value of an _expression_ or _markup_ is used in its _formatting_. 2794*912701f9SAndroid Build Coastguard Worker 2795*912701f9SAndroid Build Coastguard WorkerThe form that resolved values take is implementation-dependent, 2796*912701f9SAndroid Build Coastguard Workerand different implementations MAY choose to perform different levels of resolution. 2797*912701f9SAndroid Build Coastguard Worker 2798*912701f9SAndroid Build Coastguard Worker> For example, the resolved value of the _expression_ `{|0.40| :number style=percent}` 2799*912701f9SAndroid Build Coastguard Worker> could be an object such as 2800*912701f9SAndroid Build Coastguard Worker> 2801*912701f9SAndroid Build Coastguard Worker> ``` 2802*912701f9SAndroid Build Coastguard Worker> { value: Number('0.40'), 2803*912701f9SAndroid Build Coastguard Worker> formatter: NumberFormat(locale, { style: 'percent' }) } 2804*912701f9SAndroid Build Coastguard Worker> ``` 2805*912701f9SAndroid Build Coastguard Worker> 2806*912701f9SAndroid Build Coastguard Worker> Alternatively, it could be an instance of an ICU4J `FormattedNumber`, 2807*912701f9SAndroid Build Coastguard Worker> or some other locally appropriate value. 2808*912701f9SAndroid Build Coastguard Worker 2809*912701f9SAndroid Build Coastguard WorkerDepending on the presence or absence of a _variable_ or _literal_ operand 2810*912701f9SAndroid Build Coastguard Workerand a _function_, _private-use annotation_, or _reserved annotation_, 2811*912701f9SAndroid Build Coastguard Workerthe resolved value of the _expression_ is determined as follows: 2812*912701f9SAndroid Build Coastguard Worker 2813*912701f9SAndroid Build Coastguard WorkerIf the _expression_ contains a _reserved annotation_, 2814*912701f9SAndroid Build Coastguard Workeran _Unsupported Expression_ error is emitted and 2815*912701f9SAndroid Build Coastguard Workera _fallback value_ is used as the resolved value of the _expression_. 2816*912701f9SAndroid Build Coastguard Worker 2817*912701f9SAndroid Build Coastguard WorkerElse, if the _expression_ contains a _private-use annotation_, 2818*912701f9SAndroid Build Coastguard Workerits resolved value is defined according to the implementation's specification. 2819*912701f9SAndroid Build Coastguard Worker 2820*912701f9SAndroid Build Coastguard WorkerElse, if the _expression_ contains an _annotation_, 2821*912701f9SAndroid Build Coastguard Workerits resolved value is defined by _function resolution_. 2822*912701f9SAndroid Build Coastguard Worker 2823*912701f9SAndroid Build Coastguard WorkerElse, if the _expression_ consists of a _variable_, 2824*912701f9SAndroid Build Coastguard Workerits resolved value is defined by _variable resolution_. 2825*912701f9SAndroid Build Coastguard WorkerAn implementation MAY perform additional processing 2826*912701f9SAndroid Build Coastguard Workerwhen resolving the value of an _expression_ 2827*912701f9SAndroid Build Coastguard Workerthat consists only of a _variable_. 2828*912701f9SAndroid Build Coastguard Worker 2829*912701f9SAndroid Build Coastguard Worker> For example, it could apply _function resolution_ using a _function_ 2830*912701f9SAndroid Build Coastguard Worker> and a set of _options_ chosen based on the value or type of the _variable_. 2831*912701f9SAndroid Build Coastguard Worker> So, given a _message_ like this: 2832*912701f9SAndroid Build Coastguard Worker> 2833*912701f9SAndroid Build Coastguard Worker> ``` 2834*912701f9SAndroid Build Coastguard Worker> Today is {$date} 2835*912701f9SAndroid Build Coastguard Worker> ``` 2836*912701f9SAndroid Build Coastguard Worker> 2837*912701f9SAndroid Build Coastguard Worker> If the value passed in the _variable_ were a date object, 2838*912701f9SAndroid Build Coastguard Worker> such as a JavaScript `Date` or a Java `java.util.Date` or `java.time.Temporal`, 2839*912701f9SAndroid Build Coastguard Worker> the implementation could interpret the _placeholder_ `{$date}` as if 2840*912701f9SAndroid Build Coastguard Worker> the pattern included the function `:datetime` with some set of default options. 2841*912701f9SAndroid Build Coastguard Worker 2842*912701f9SAndroid Build Coastguard WorkerElse, the _expression_ consists of a _literal_. 2843*912701f9SAndroid Build Coastguard WorkerIts resolved value is defined by _literal resolution_. 2844*912701f9SAndroid Build Coastguard Worker 2845*912701f9SAndroid Build Coastguard Worker> **Note** 2846*912701f9SAndroid Build Coastguard Worker> This means that a _literal_ value with no _annotation_ 2847*912701f9SAndroid Build Coastguard Worker> is always treated as a string. 2848*912701f9SAndroid Build Coastguard Worker> To represent values that are not strings as a _literal_, 2849*912701f9SAndroid Build Coastguard Worker> an _annotation_ needs to be provided: 2850*912701f9SAndroid Build Coastguard Worker> 2851*912701f9SAndroid Build Coastguard Worker> ``` 2852*912701f9SAndroid Build Coastguard Worker> .local $aNumber = {1234 :number} 2853*912701f9SAndroid Build Coastguard Worker> .local $aDate = {|2023-08-30| :datetime} 2854*912701f9SAndroid Build Coastguard Worker> .local $aFoo = {|some foo| :foo} 2855*912701f9SAndroid Build Coastguard Worker> {{You have {42 :number}}} 2856*912701f9SAndroid Build Coastguard Worker> ``` 2857*912701f9SAndroid Build Coastguard Worker 2858*912701f9SAndroid Build Coastguard Worker#### Literal Resolution 2859*912701f9SAndroid Build Coastguard Worker 2860*912701f9SAndroid Build Coastguard WorkerThe resolved value of a _text_ or a _literal_ is 2861*912701f9SAndroid Build Coastguard Workerthe character sequence of the _text_ or _literal_ 2862*912701f9SAndroid Build Coastguard Workerafter any character escape has been converted to the escaped character. 2863*912701f9SAndroid Build Coastguard Worker 2864*912701f9SAndroid Build Coastguard WorkerWhen a _literal_ is used as an _operand_ 2865*912701f9SAndroid Build Coastguard Workeror on the right-hand side of an _option_, 2866*912701f9SAndroid Build Coastguard Workerthe formatting function MUST treat its resolved value the same 2867*912701f9SAndroid Build Coastguard Workerwhether its value was originally _quoted_ or _unquoted_. 2868*912701f9SAndroid Build Coastguard Worker 2869*912701f9SAndroid Build Coastguard Worker> For example, 2870*912701f9SAndroid Build Coastguard Worker> the _option_ `foo=42` and the _option_ `foo=|42|` are treated as identical. 2871*912701f9SAndroid Build Coastguard Worker 2872*912701f9SAndroid Build Coastguard WorkerThe resolution of a _text_ or _literal_ MUST resolve to a string. 2873*912701f9SAndroid Build Coastguard Worker 2874*912701f9SAndroid Build Coastguard Worker#### Variable Resolution 2875*912701f9SAndroid Build Coastguard Worker 2876*912701f9SAndroid Build Coastguard WorkerTo resolve the value of a _variable_, 2877*912701f9SAndroid Build Coastguard Workerits _name_ is used to identify either a local variable or an input variable. 2878*912701f9SAndroid Build Coastguard WorkerIf a _declaration_ exists for the _variable_, its resolved value is used. 2879*912701f9SAndroid Build Coastguard WorkerOtherwise, the _variable_ is an implicit reference to an input value, 2880*912701f9SAndroid Build Coastguard Workerand its value is looked up from the _formatting context_ _input mapping_. 2881*912701f9SAndroid Build Coastguard Worker 2882*912701f9SAndroid Build Coastguard WorkerThe resolution of a _variable_ MAY fail if no value is identified for its _name_. 2883*912701f9SAndroid Build Coastguard WorkerIf this happens, an _Unresolved Variable_ error MUST be emitted. 2884*912701f9SAndroid Build Coastguard WorkerIf a _variable_ would resolve to a _fallback value_, 2885*912701f9SAndroid Build Coastguard Workerthis MUST also be considered a failure. 2886*912701f9SAndroid Build Coastguard Worker 2887*912701f9SAndroid Build Coastguard Worker#### Function Resolution 2888*912701f9SAndroid Build Coastguard Worker 2889*912701f9SAndroid Build Coastguard WorkerTo resolve an _expression_ with a _function_ _annotation_, 2890*912701f9SAndroid Build Coastguard Workerthe following steps are taken: 2891*912701f9SAndroid Build Coastguard Worker 2892*912701f9SAndroid Build Coastguard Worker1. If the _expression_ includes an _operand_, resolve its value. 2893*912701f9SAndroid Build Coastguard Worker If this fails, use a _fallback value_ for the _expression_. 2894*912701f9SAndroid Build Coastguard Worker2. Resolve the _identifier_ of the _function_ and, based on the starting sigil, 2895*912701f9SAndroid Build Coastguard Worker find the appropriate function implementation to call. 2896*912701f9SAndroid Build Coastguard Worker If the implementation cannot find the function, 2897*912701f9SAndroid Build Coastguard Worker or if the _identifier_ includes a _namespace_ that the implementation does not support, 2898*912701f9SAndroid Build Coastguard Worker emit an _Unknown Function_ error 2899*912701f9SAndroid Build Coastguard Worker and use a _fallback value_ for the _expression_. 2900*912701f9SAndroid Build Coastguard Worker 2901*912701f9SAndroid Build Coastguard Worker Implementations are not required to implement _namespaces_ or installable 2902*912701f9SAndroid Build Coastguard Worker _function registries_. 2903*912701f9SAndroid Build Coastguard Worker 2904*912701f9SAndroid Build Coastguard Worker3. Perform _option resolution_. 2905*912701f9SAndroid Build Coastguard Worker 2906*912701f9SAndroid Build Coastguard Worker4. Call the function implementation with the following arguments: 2907*912701f9SAndroid Build Coastguard Worker 2908*912701f9SAndroid Build Coastguard Worker - The current _locale_. 2909*912701f9SAndroid Build Coastguard Worker - The resolved mapping of _options_. 2910*912701f9SAndroid Build Coastguard Worker - If the _expression_ includes an _operand_, its resolved value. 2911*912701f9SAndroid Build Coastguard Worker 2912*912701f9SAndroid Build Coastguard Worker The form that resolved _operand_ and _option_ values take is implementation-defined. 2913*912701f9SAndroid Build Coastguard Worker 2914*912701f9SAndroid Build Coastguard Worker A _declaration_ binds the resolved value of an _expression_ 2915*912701f9SAndroid Build Coastguard Worker to a _variable_. 2916*912701f9SAndroid Build Coastguard Worker Thus, the result of one _function_ is potentially the _operand_ 2917*912701f9SAndroid Build Coastguard Worker of another _function_, 2918*912701f9SAndroid Build Coastguard Worker or the value of one of the _options_ for another function. 2919*912701f9SAndroid Build Coastguard Worker For example, in 2920*912701f9SAndroid Build Coastguard Worker ``` 2921*912701f9SAndroid Build Coastguard Worker .input {$n :number minIntegerDigits=3} 2922*912701f9SAndroid Build Coastguard Worker .local $n1 = {$n :number maxFractionDigits=3} 2923*912701f9SAndroid Build Coastguard Worker ``` 2924*912701f9SAndroid Build Coastguard Worker the value bound to `$n` is the 2925*912701f9SAndroid Build Coastguard Worker resolved value used as the _operand_ 2926*912701f9SAndroid Build Coastguard Worker of the `:number` _function_ 2927*912701f9SAndroid Build Coastguard Worker when resolving the value of the _variable_ `$n1`. 2928*912701f9SAndroid Build Coastguard Worker 2929*912701f9SAndroid Build Coastguard Worker Implementations that provide a means for defining custom functions 2930*912701f9SAndroid Build Coastguard Worker SHOULD provide a means for function implementations 2931*912701f9SAndroid Build Coastguard Worker to return values that contain enough information 2932*912701f9SAndroid Build Coastguard Worker (e.g. a representation of 2933*912701f9SAndroid Build Coastguard Worker the resolved _operand_ and _option_ values 2934*912701f9SAndroid Build Coastguard Worker that the function was called with) 2935*912701f9SAndroid Build Coastguard Worker to be used as arguments to subsequent calls 2936*912701f9SAndroid Build Coastguard Worker to the function implementations. 2937*912701f9SAndroid Build Coastguard Worker For example, an implementation might define an interface that allows custom function implementation. 2938*912701f9SAndroid Build Coastguard Worker Such an interface SHOULD define an implementation-specific 2939*912701f9SAndroid Build Coastguard Worker argument type `T` and return type `U` 2940*912701f9SAndroid Build Coastguard Worker for implementations of functions 2941*912701f9SAndroid Build Coastguard Worker such that `U` can be coerced to `T`. 2942*912701f9SAndroid Build Coastguard Worker Implementations of a _function_ SHOULD emit an 2943*912701f9SAndroid Build Coastguard Worker _Invalid Expression_ error for _operands_ whose resolved value 2944*912701f9SAndroid Build Coastguard Worker or type is not supported. 2945*912701f9SAndroid Build Coastguard Worker 2946*912701f9SAndroid Build Coastguard Worker> [!NOTE] 2947*912701f9SAndroid Build Coastguard Worker> The behavior of the previous example is 2948*912701f9SAndroid Build Coastguard Worker> currently implementation-dependent. Supposing that 2949*912701f9SAndroid Build Coastguard Worker> the external input variable `n` is bound to the string `"1"`, 2950*912701f9SAndroid Build Coastguard Worker> and that the implementation formats to a string, 2951*912701f9SAndroid Build Coastguard Worker> the formatted result of the following message: 2952*912701f9SAndroid Build Coastguard Worker> 2953*912701f9SAndroid Build Coastguard Worker> ``` 2954*912701f9SAndroid Build Coastguard Worker> .input {$n :number minIntegerDigits=3} 2955*912701f9SAndroid Build Coastguard Worker> .local $n1 = {$n :number maxFractionDigits=3} 2956*912701f9SAndroid Build Coastguard Worker> {{$n1}} 2957*912701f9SAndroid Build Coastguard Worker> ``` 2958*912701f9SAndroid Build Coastguard Worker> 2959*912701f9SAndroid Build Coastguard Worker> is currently implementation-dependent. 2960*912701f9SAndroid Build Coastguard Worker> Depending on whether the options are preserved 2961*912701f9SAndroid Build Coastguard Worker> between the resolution of the first `:number` _annotation_ 2962*912701f9SAndroid Build Coastguard Worker> and the resolution of the second `:number` _annotation_, 2963*912701f9SAndroid Build Coastguard Worker> a conformant implementation 2964*912701f9SAndroid Build Coastguard Worker> could produce either "001.000" or "1.000" 2965*912701f9SAndroid Build Coastguard Worker> 2966*912701f9SAndroid Build Coastguard Worker> Each function **specification** MAY have 2967*912701f9SAndroid Build Coastguard Worker> its own rules to preserve some options in the returned structure 2968*912701f9SAndroid Build Coastguard Worker> and discard others. 2969*912701f9SAndroid Build Coastguard Worker> In instances where a function specification does not determine whether an option is preserved or discarded, 2970*912701f9SAndroid Build Coastguard Worker> each function **implementation** of that specification MAY have 2971*912701f9SAndroid Build Coastguard Worker> its own rules to preserve some options in the returned structure 2972*912701f9SAndroid Build Coastguard Worker> and discard others. 2973*912701f9SAndroid Build Coastguard Worker> 2974*912701f9SAndroid Build Coastguard Worker 2975*912701f9SAndroid Build Coastguard Worker> [!NOTE] 2976*912701f9SAndroid Build Coastguard Worker> During the Technical Preview, 2977*912701f9SAndroid Build Coastguard Worker> feedback on how the registry describes 2978*912701f9SAndroid Build Coastguard Worker> the flow of _resolved values_ and _options_ 2979*912701f9SAndroid Build Coastguard Worker> from one _function_ to another, 2980*912701f9SAndroid Build Coastguard Worker> and on what requirements this specification should impose, 2981*912701f9SAndroid Build Coastguard Worker> is highly desired. 2982*912701f9SAndroid Build Coastguard Worker 2983*912701f9SAndroid Build Coastguard Worker An implementation MAY pass additional arguments to the function, 2984*912701f9SAndroid Build Coastguard Worker as long as reasonable precautions are taken to keep the function interface 2985*912701f9SAndroid Build Coastguard Worker simple and minimal, and avoid introducing potential security vulnerabilities. 2986*912701f9SAndroid Build Coastguard Worker 2987*912701f9SAndroid Build Coastguard Worker An implementation MAY define its own functions. 2988*912701f9SAndroid Build Coastguard Worker An implementation MAY allow custom functions to be defined by users. 2989*912701f9SAndroid Build Coastguard Worker 2990*912701f9SAndroid Build Coastguard Worker Function access to the _formatting context_ MUST be minimal and read-only, 2991*912701f9SAndroid Build Coastguard Worker and execution time SHOULD be limited. 2992*912701f9SAndroid Build Coastguard Worker 2993*912701f9SAndroid Build Coastguard Worker Implementation-defined _functions_ SHOULD use an implementation-defined _namespace_. 2994*912701f9SAndroid Build Coastguard Worker 2995*912701f9SAndroid Build Coastguard Worker5. If the call succeeds, 2996*912701f9SAndroid Build Coastguard Worker resolve the value of the _expression_ as the result of that function call. 2997*912701f9SAndroid Build Coastguard Worker 2998*912701f9SAndroid Build Coastguard Worker If the call fails or does not return a valid value, 2999*912701f9SAndroid Build Coastguard Worker emit a _Invalid Expression_ error. 3000*912701f9SAndroid Build Coastguard Worker 3001*912701f9SAndroid Build Coastguard Worker Implementations MAY provide a mechanism for the _function_ to provide 3002*912701f9SAndroid Build Coastguard Worker additional detail about internal failures. 3003*912701f9SAndroid Build Coastguard Worker Specifically, if the cause of the failure was that the datatype, value, or format of the 3004*912701f9SAndroid Build Coastguard Worker _operand_ did not match that expected by the _function_, 3005*912701f9SAndroid Build Coastguard Worker the _function_ might cause an _Operand Mismatch Error_ to be emitted. 3006*912701f9SAndroid Build Coastguard Worker 3007*912701f9SAndroid Build Coastguard Worker In all failure cases, use the _fallback value_ for the _expression_ as the resolved value. 3008*912701f9SAndroid Build Coastguard Worker 3009*912701f9SAndroid Build Coastguard Worker##### Option Resolution 3010*912701f9SAndroid Build Coastguard Worker 3011*912701f9SAndroid Build Coastguard WorkerThe result of resolving _option_ values is an unordered mapping of string identifiers to values. 3012*912701f9SAndroid Build Coastguard Worker 3013*912701f9SAndroid Build Coastguard WorkerFor each _option_: 3014*912701f9SAndroid Build Coastguard Worker 3015*912701f9SAndroid Build Coastguard Worker- Resolve the _identifier_ of the _option_. 3016*912701f9SAndroid Build Coastguard Worker- If the _option_'s right-hand side successfully resolves to a value, 3017*912701f9SAndroid Build Coastguard Worker bind the _identifier_ of the _option_ to the resolved value in the mapping. 3018*912701f9SAndroid Build Coastguard Worker- Otherwise, bind the _identifier_ of the _option_ to an unresolved value in the mapping. 3019*912701f9SAndroid Build Coastguard Worker Implementations MAY later remove this value before calling the _function_. 3020*912701f9SAndroid Build Coastguard Worker (Note that an _Unresolved Variable_ error will have been emitted.) 3021*912701f9SAndroid Build Coastguard Worker 3022*912701f9SAndroid Build Coastguard WorkerErrors MAY be emitted during _option resolution_, 3023*912701f9SAndroid Build Coastguard Workerbut it always resolves to some mapping of string identifiers to values. 3024*912701f9SAndroid Build Coastguard WorkerThis mapping can be empty. 3025*912701f9SAndroid Build Coastguard Worker 3026*912701f9SAndroid Build Coastguard Worker#### Markup Resolution 3027*912701f9SAndroid Build Coastguard Worker 3028*912701f9SAndroid Build Coastguard WorkerUnlike _functions_, the resolution of _markup_ is not customizable. 3029*912701f9SAndroid Build Coastguard Worker 3030*912701f9SAndroid Build Coastguard WorkerThe resolved value of _markup_ includes the following fields: 3031*912701f9SAndroid Build Coastguard Worker 3032*912701f9SAndroid Build Coastguard Worker- The type of the markup: open, standalone, or close 3033*912701f9SAndroid Build Coastguard Worker- The _identifier_ of the _markup_ 3034*912701f9SAndroid Build Coastguard Worker- The resolved _options_ values after _option resolution_. 3035*912701f9SAndroid Build Coastguard Worker 3036*912701f9SAndroid Build Coastguard WorkerThe resolution of _markup_ MUST always succeed. 3037*912701f9SAndroid Build Coastguard Worker 3038*912701f9SAndroid Build Coastguard Worker#### Fallback Resolution 3039*912701f9SAndroid Build Coastguard Worker 3040*912701f9SAndroid Build Coastguard WorkerA **_fallback value_** is the resolved value for an _expression_ that fails to resolve. 3041*912701f9SAndroid Build Coastguard Worker 3042*912701f9SAndroid Build Coastguard WorkerAn _expression_ fails to resolve when: 3043*912701f9SAndroid Build Coastguard Worker 3044*912701f9SAndroid Build Coastguard Worker- A _variable_ used as an _operand_ (with or without an _annotation_) fails to resolve. 3045*912701f9SAndroid Build Coastguard Worker * Note that this does not include a _variable_ used as an _option_ value. 3046*912701f9SAndroid Build Coastguard Worker- A _function_ _annotation_ fails to resolve. 3047*912701f9SAndroid Build Coastguard Worker- A _private-use annotation_ is unsupported by the implementation or if 3048*912701f9SAndroid Build Coastguard Worker a _private-use annotation_ fails to resolve. 3049*912701f9SAndroid Build Coastguard Worker- The _expression_ has a _reserved annotation_. 3050*912701f9SAndroid Build Coastguard Worker 3051*912701f9SAndroid Build Coastguard WorkerThe _fallback value_ depends on the contents of the _expression_: 3052*912701f9SAndroid Build Coastguard Worker 3053*912701f9SAndroid Build Coastguard Worker- _expression_ with _literal_ _operand_ (_quoted_ or _unquoted_): 3054*912701f9SAndroid Build Coastguard Worker U+007C VERTICAL LINE `|` 3055*912701f9SAndroid Build Coastguard Worker followed by the value of the _literal_ 3056*912701f9SAndroid Build Coastguard Worker with escaping applied to U+005C REVERSE SOLIDUS `\` and U+007C VERTICAL LINE `|`, 3057*912701f9SAndroid Build Coastguard Worker and then by U+007C VERTICAL LINE `|`. 3058*912701f9SAndroid Build Coastguard Worker 3059*912701f9SAndroid Build Coastguard Worker > Examples: 3060*912701f9SAndroid Build Coastguard Worker > In a context where `:func` fails to resolve, 3061*912701f9SAndroid Build Coastguard Worker > `{42 :func}` resolves to the _fallback value_ `|42|` and 3062*912701f9SAndroid Build Coastguard Worker > `{|C:\\| :func}` resolves to the _fallback value_ `|C:\\|`. 3063*912701f9SAndroid Build Coastguard Worker > In any context, `{|| @reserved}` resolves to the _fallback value_ `||`. 3064*912701f9SAndroid Build Coastguard Worker 3065*912701f9SAndroid Build Coastguard Worker- _expression_ with _variable_ _operand_ referring to a local _declaration_ (with or without an _annotation_): 3066*912701f9SAndroid Build Coastguard Worker the _value_ to which it resolves (which may already be a _fallback value_) 3067*912701f9SAndroid Build Coastguard Worker 3068*912701f9SAndroid Build Coastguard Worker > Examples: 3069*912701f9SAndroid Build Coastguard Worker > In a context where `:func` fails to resolve, 3070*912701f9SAndroid Build Coastguard Worker > the _pattern_'s _expression_ in `.local $var={|val|} {{{$val :func}}}` 3071*912701f9SAndroid Build Coastguard Worker > resolves to the _fallback value_ `|val|` and the message formats to `{|val|}`. 3072*912701f9SAndroid Build Coastguard Worker > In a context where `:now` fails to resolve but `:datetime` does not, 3073*912701f9SAndroid Build Coastguard Worker > the _pattern_'s _expression_ in 3074*912701f9SAndroid Build Coastguard Worker > ``` 3075*912701f9SAndroid Build Coastguard Worker > .local $t = {:now format=iso8601} 3076*912701f9SAndroid Build Coastguard Worker > .local $pretty_t = {$t :datetime} 3077*912701f9SAndroid Build Coastguard Worker > {{{$pretty_t}}} 3078*912701f9SAndroid Build Coastguard Worker > ``` 3079*912701f9SAndroid Build Coastguard Worker > (transitively) resolves to the _fallback value_ `:now` and 3080*912701f9SAndroid Build Coastguard Worker > the message formats to `{:now}`. 3081*912701f9SAndroid Build Coastguard Worker 3082*912701f9SAndroid Build Coastguard Worker- _expression_ with _variable_ _operand_ not referring to a local _declaration_ (with or without an _annotation_): 3083*912701f9SAndroid Build Coastguard Worker U+0024 DOLLAR SIGN `$` followed by the _name_ of the _variable_ 3084*912701f9SAndroid Build Coastguard Worker 3085*912701f9SAndroid Build Coastguard Worker > Examples: 3086*912701f9SAndroid Build Coastguard Worker > In a context where `$var` fails to resolve, `{$var}` and `{$var :number}` and `{$var @reserved}` 3087*912701f9SAndroid Build Coastguard Worker > all resolve to the _fallback value_ `$var`. 3088*912701f9SAndroid Build Coastguard Worker > In a context where `:func` fails to resolve, 3089*912701f9SAndroid Build Coastguard Worker > the _pattern_'s _expression_ in `.input $arg {{{$arg :func}}}` 3090*912701f9SAndroid Build Coastguard Worker > resolves to the _fallback value_ `$arg` and 3091*912701f9SAndroid Build Coastguard Worker > the message formats to `{$arg}`. 3092*912701f9SAndroid Build Coastguard Worker 3093*912701f9SAndroid Build Coastguard Worker- _function_ _expression_ with no _operand_: 3094*912701f9SAndroid Build Coastguard Worker U+003A COLON `:` followed by the _function_ _identifier_ 3095*912701f9SAndroid Build Coastguard Worker 3096*912701f9SAndroid Build Coastguard Worker > Examples: 3097*912701f9SAndroid Build Coastguard Worker > In a context where `:func` fails to resolve, `{:func}` resolves to the _fallback value_ `:func`. 3098*912701f9SAndroid Build Coastguard Worker > In a context where `:ns:func` fails to resolve, `{:ns:func}` resolves to the _fallback value_ `:ns:func`. 3099*912701f9SAndroid Build Coastguard Worker 3100*912701f9SAndroid Build Coastguard Worker- unsupported _private-use annotation_ or _reserved annotation_ with no _operand_: 3101*912701f9SAndroid Build Coastguard Worker the _annotation_ starting sigil 3102*912701f9SAndroid Build Coastguard Worker 3103*912701f9SAndroid Build Coastguard Worker > Examples: 3104*912701f9SAndroid Build Coastguard Worker > In any context, `{@reserved}` and `{@reserved |...|}` both resolve to the _fallback value_ `@`. 3105*912701f9SAndroid Build Coastguard Worker 3106*912701f9SAndroid Build Coastguard Worker- supported _private-use annotation_ with no _operand_: 3107*912701f9SAndroid Build Coastguard Worker the _annotation_ starting sigil, optionally followed by implementation-defined details 3108*912701f9SAndroid Build Coastguard Worker conforming with patterns in the other cases (such as quoting literals). 3109*912701f9SAndroid Build Coastguard Worker If details are provided, they SHOULD NOT leak potentially private information. 3110*912701f9SAndroid Build Coastguard Worker 3111*912701f9SAndroid Build Coastguard Worker > Examples: 3112*912701f9SAndroid Build Coastguard Worker > In a context where `^` expressions are used for comments, `{^▽^}` might resolve to the _fallback value_ `^`. 3113*912701f9SAndroid Build Coastguard Worker > In a context where `&` expressions are _function_-like macro invocations, `{&foo |...|}` might resolve to the _fallback value_ `&foo`. 3114*912701f9SAndroid Build Coastguard Worker 3115*912701f9SAndroid Build Coastguard Worker- Otherwise: the U+FFFD REPLACEMENT CHARACTER `�` 3116*912701f9SAndroid Build Coastguard Worker 3117*912701f9SAndroid Build Coastguard Worker This is not currently used by any expression, but may apply in future revisions. 3118*912701f9SAndroid Build Coastguard Worker 3119*912701f9SAndroid Build Coastguard Worker_Option_ _identifiers_ and values are not included in the _fallback value_. 3120*912701f9SAndroid Build Coastguard Worker 3121*912701f9SAndroid Build Coastguard Worker_Pattern selection_ is not supported for _fallback values_. 3122*912701f9SAndroid Build Coastguard Worker 3123*912701f9SAndroid Build Coastguard Worker### Pattern Selection 3124*912701f9SAndroid Build Coastguard Worker 3125*912701f9SAndroid Build Coastguard WorkerWhen a _message_ contains a _matcher_ with one or more _selectors_, 3126*912701f9SAndroid Build Coastguard Workerthe implementation needs to determine which _variant_ will be used 3127*912701f9SAndroid Build Coastguard Workerto provide the _pattern_ for the formatting operation. 3128*912701f9SAndroid Build Coastguard WorkerThis is done by ordering and filtering the available _variant_ statements 3129*912701f9SAndroid Build Coastguard Workeraccording to their _key_ values and selecting the first one. 3130*912701f9SAndroid Build Coastguard Worker 3131*912701f9SAndroid Build Coastguard Worker> [!NOTE] 3132*912701f9SAndroid Build Coastguard Worker> At least one _variant_ is required to have all of its _keys_ consist of 3133*912701f9SAndroid Build Coastguard Worker> the fallback value `*`. 3134*912701f9SAndroid Build Coastguard Worker> Some _selectors_ might be implemented in a way that the key value `*` 3135*912701f9SAndroid Build Coastguard Worker> cannot be selected in a _valid_ _message_. 3136*912701f9SAndroid Build Coastguard Worker> In other cases, this key value might be unreachable only in certain locales. 3137*912701f9SAndroid Build Coastguard Worker> This could result in the need in some locales to create 3138*912701f9SAndroid Build Coastguard Worker> one or more _variants_ that do not make sense grammatically for that language. 3139*912701f9SAndroid Build Coastguard Worker> > For example, in the `pl` (Polish) locale, this _message_ cannot reach 3140*912701f9SAndroid Build Coastguard Worker> > the `*` _variant_: 3141*912701f9SAndroid Build Coastguard Worker> > ``` 3142*912701f9SAndroid Build Coastguard Worker> > .match {$num :integer} 3143*912701f9SAndroid Build Coastguard Worker> > 0 {{ }} 3144*912701f9SAndroid Build Coastguard Worker> > one {{ }} 3145*912701f9SAndroid Build Coastguard Worker> > few {{ }} 3146*912701f9SAndroid Build Coastguard Worker> > many {{ }} 3147*912701f9SAndroid Build Coastguard Worker> > * {{Only used by fractions in Polish.}} 3148*912701f9SAndroid Build Coastguard Worker> > ``` 3149*912701f9SAndroid Build Coastguard Worker> 3150*912701f9SAndroid Build Coastguard Worker> In the Tech Preview, feedback from users and implementers is desired about 3151*912701f9SAndroid Build Coastguard Worker> whether to relax the requirement that such a "fallback _variant_" appear in 3152*912701f9SAndroid Build Coastguard Worker> every message, versus the potential for a _message_ to fail at runtime 3153*912701f9SAndroid Build Coastguard Worker> because no matching _variant_ is available. 3154*912701f9SAndroid Build Coastguard Worker 3155*912701f9SAndroid Build Coastguard WorkerThe number of _keys_ in each _variant_ MUST equal the number of _selectors_. 3156*912701f9SAndroid Build Coastguard Worker 3157*912701f9SAndroid Build Coastguard WorkerEach _key_ corresponds to a _selector_ by its position in the _variant_. 3158*912701f9SAndroid Build Coastguard Worker 3159*912701f9SAndroid Build Coastguard Worker> For example, in this message: 3160*912701f9SAndroid Build Coastguard Worker> 3161*912701f9SAndroid Build Coastguard Worker> ``` 3162*912701f9SAndroid Build Coastguard Worker> .match {:one} {:two} {:three} 3163*912701f9SAndroid Build Coastguard Worker> 1 2 3 {{ ... }} 3164*912701f9SAndroid Build Coastguard Worker> ``` 3165*912701f9SAndroid Build Coastguard Worker> 3166*912701f9SAndroid Build Coastguard Worker> The first _key_ `1` corresponds to the first _selector_ (`{:one}`), 3167*912701f9SAndroid Build Coastguard Worker> the second _key_ `2` to the second _selector_ (`{:two}`), 3168*912701f9SAndroid Build Coastguard Worker> and the third _key_ `3` to the third _selector_ (`{:three}`). 3169*912701f9SAndroid Build Coastguard Worker 3170*912701f9SAndroid Build Coastguard WorkerTo determine which _variant_ best matches a given set of inputs, 3171*912701f9SAndroid Build Coastguard Workereach _selector_ is used in turn to order and filter the list of _variants_. 3172*912701f9SAndroid Build Coastguard Worker 3173*912701f9SAndroid Build Coastguard WorkerEach _variant_ with a _key_ that does not match its corresponding _selector_ 3174*912701f9SAndroid Build Coastguard Workeris omitted from the list of _variants_. 3175*912701f9SAndroid Build Coastguard WorkerThe remaining _variants_ are sorted according to the _selector_'s _key_-ordering preference. 3176*912701f9SAndroid Build Coastguard WorkerEarlier _selectors_ in the _matcher_'s list of _selectors_ have a higher priority than later ones. 3177*912701f9SAndroid Build Coastguard Worker 3178*912701f9SAndroid Build Coastguard WorkerWhen all of the _selectors_ have been processed, 3179*912701f9SAndroid Build Coastguard Workerthe earliest-sorted _variant_ in the remaining list of _variants_ is selected. 3180*912701f9SAndroid Build Coastguard Worker 3181*912701f9SAndroid Build Coastguard Worker> [!NOTE] 3182*912701f9SAndroid Build Coastguard Worker> A _selector_ is not a _declaration_. 3183*912701f9SAndroid Build Coastguard Worker> Even when the same _function_ can be used for both formatting and selection 3184*912701f9SAndroid Build Coastguard Worker> of a given _operand_ 3185*912701f9SAndroid Build Coastguard Worker> the _annotation_ that appears in a _selector_ has no effect on subsequent 3186*912701f9SAndroid Build Coastguard Worker> _selectors_ nor on the formatting used in _placeholders_. 3187*912701f9SAndroid Build Coastguard Worker> To use the same value for selection and formatting, 3188*912701f9SAndroid Build Coastguard Worker> set its value with a `.input` or `.local` _declaration_. 3189*912701f9SAndroid Build Coastguard Worker 3190*912701f9SAndroid Build Coastguard WorkerThis selection method is defined in more detail below. 3191*912701f9SAndroid Build Coastguard WorkerAn implementation MAY use any pattern selection method, 3192*912701f9SAndroid Build Coastguard Workeras long as its observable behavior matches the results of the method defined here. 3193*912701f9SAndroid Build Coastguard Worker 3194*912701f9SAndroid Build Coastguard WorkerIf the message being formatted has any _Syntax Errors_ or _Data Model Errors_, 3195*912701f9SAndroid Build Coastguard Workerthe result of pattern selection MUST be a pattern resolving to a single _fallback value_ 3196*912701f9SAndroid Build Coastguard Workerusing the message's fallback string defined in the _formatting context_ 3197*912701f9SAndroid Build Coastguard Workeror if this is not available or empty, the U+FFFD REPLACEMENT CHARACTER `�`. 3198*912701f9SAndroid Build Coastguard Worker 3199*912701f9SAndroid Build Coastguard Worker#### Resolve Selectors 3200*912701f9SAndroid Build Coastguard Worker 3201*912701f9SAndroid Build Coastguard WorkerFirst, resolve the values of each _selector_: 3202*912701f9SAndroid Build Coastguard Worker 3203*912701f9SAndroid Build Coastguard Worker1. Let `res` be a new empty list of resolved values that support selection. 3204*912701f9SAndroid Build Coastguard Worker1. For each _selector_ `sel`, in source order, 3205*912701f9SAndroid Build Coastguard Worker 1. Let `rv` be the resolved value of `sel`. 3206*912701f9SAndroid Build Coastguard Worker 1. If selection is supported for `rv`: 3207*912701f9SAndroid Build Coastguard Worker 1. Append `rv` as the last element of the list `res`. 3208*912701f9SAndroid Build Coastguard Worker 1. Else: 3209*912701f9SAndroid Build Coastguard Worker 1. Let `nomatch` be a resolved value for which selection always fails. 3210*912701f9SAndroid Build Coastguard Worker 1. Append `nomatch` as the last element of the list `res`. 3211*912701f9SAndroid Build Coastguard Worker 1. Emit a _Selection Error_. 3212*912701f9SAndroid Build Coastguard Worker 3213*912701f9SAndroid Build Coastguard WorkerThe form of the resolved values is determined by each implementation, 3214*912701f9SAndroid Build Coastguard Workeralong with the manner of determining their support for selection. 3215*912701f9SAndroid Build Coastguard Worker 3216*912701f9SAndroid Build Coastguard Worker#### Resolve Preferences 3217*912701f9SAndroid Build Coastguard Worker 3218*912701f9SAndroid Build Coastguard WorkerNext, using `res`, resolve the preferential order for all message keys: 3219*912701f9SAndroid Build Coastguard Worker 3220*912701f9SAndroid Build Coastguard Worker1. Let `pref` be a new empty list of lists of strings. 3221*912701f9SAndroid Build Coastguard Worker1. For each index `i` in `res`: 3222*912701f9SAndroid Build Coastguard Worker 1. Let `keys` be a new empty list of strings. 3223*912701f9SAndroid Build Coastguard Worker 1. For each _variant_ `var` of the message: 3224*912701f9SAndroid Build Coastguard Worker 1. Let `key` be the `var` key at position `i`. 3225*912701f9SAndroid Build Coastguard Worker 1. If `key` is not the catch-all key `'*'`: 3226*912701f9SAndroid Build Coastguard Worker 1. Assert that `key` is a _literal_. 3227*912701f9SAndroid Build Coastguard Worker 1. Let `ks` be the resolved value of `key`. 3228*912701f9SAndroid Build Coastguard Worker 1. Append `ks` as the last element of the list `keys`. 3229*912701f9SAndroid Build Coastguard Worker 1. Let `rv` be the resolved value at index `i` of `res`. 3230*912701f9SAndroid Build Coastguard Worker 1. Let `matches` be the result of calling the method MatchSelectorKeys(`rv`, `keys`) 3231*912701f9SAndroid Build Coastguard Worker 1. Append `matches` as the last element of the list `pref`. 3232*912701f9SAndroid Build Coastguard Worker 3233*912701f9SAndroid Build Coastguard WorkerThe method MatchSelectorKeys is determined by the implementation. 3234*912701f9SAndroid Build Coastguard WorkerIt takes as arguments a resolved _selector_ value `rv` and a list of string keys `keys`, 3235*912701f9SAndroid Build Coastguard Workerand returns a list of string keys in preferential order. 3236*912701f9SAndroid Build Coastguard WorkerThe returned list MUST contain only unique elements of the input list `keys`. 3237*912701f9SAndroid Build Coastguard WorkerThe returned list MAY be empty. 3238*912701f9SAndroid Build Coastguard WorkerThe most-preferred key is first, 3239*912701f9SAndroid Build Coastguard Workerwith each successive key appearing in order by decreasing preference. 3240*912701f9SAndroid Build Coastguard Worker 3241*912701f9SAndroid Build Coastguard Worker#### Filter Variants 3242*912701f9SAndroid Build Coastguard Worker 3243*912701f9SAndroid Build Coastguard WorkerThen, using the preferential key orders `pref`, 3244*912701f9SAndroid Build Coastguard Workerfilter the list of _variants_ to the ones that match with some preference: 3245*912701f9SAndroid Build Coastguard Worker 3246*912701f9SAndroid Build Coastguard Worker1. Let `vars` be a new empty list of _variants_. 3247*912701f9SAndroid Build Coastguard Worker1. For each _variant_ `var` of the message: 3248*912701f9SAndroid Build Coastguard Worker 1. For each index `i` in `pref`: 3249*912701f9SAndroid Build Coastguard Worker 1. Let `key` be the `var` key at position `i`. 3250*912701f9SAndroid Build Coastguard Worker 1. If `key` is the catch-all key `'*'`: 3251*912701f9SAndroid Build Coastguard Worker 1. Continue the inner loop on `pref`. 3252*912701f9SAndroid Build Coastguard Worker 1. Assert that `key` is a _literal_. 3253*912701f9SAndroid Build Coastguard Worker 1. Let `ks` be the resolved value of `key`. 3254*912701f9SAndroid Build Coastguard Worker 1. Let `matches` be the list of strings at index `i` of `pref`. 3255*912701f9SAndroid Build Coastguard Worker 1. If `matches` includes `ks`: 3256*912701f9SAndroid Build Coastguard Worker 1. Continue the inner loop on `pref`. 3257*912701f9SAndroid Build Coastguard Worker 1. Else: 3258*912701f9SAndroid Build Coastguard Worker 1. Continue the outer loop on message _variants_. 3259*912701f9SAndroid Build Coastguard Worker 1. Append `var` as the last element of the list `vars`. 3260*912701f9SAndroid Build Coastguard Worker 3261*912701f9SAndroid Build Coastguard Worker#### Sort Variants 3262*912701f9SAndroid Build Coastguard Worker 3263*912701f9SAndroid Build Coastguard WorkerFinally, sort the list of variants `vars` and select the _pattern_: 3264*912701f9SAndroid Build Coastguard Worker 3265*912701f9SAndroid Build Coastguard Worker1. Let `sortable` be a new empty list of (integer, _variant_) tuples. 3266*912701f9SAndroid Build Coastguard Worker1. For each _variant_ `var` of `vars`: 3267*912701f9SAndroid Build Coastguard Worker 1. Let `tuple` be a new tuple (-1, `var`). 3268*912701f9SAndroid Build Coastguard Worker 1. Append `tuple` as the last element of the list `sortable`. 3269*912701f9SAndroid Build Coastguard Worker1. Let `len` be the integer count of items in `pref`. 3270*912701f9SAndroid Build Coastguard Worker1. Let `i` be `len` - 1. 3271*912701f9SAndroid Build Coastguard Worker1. While `i` >= 0: 3272*912701f9SAndroid Build Coastguard Worker 1. Let `matches` be the list of strings at index `i` of `pref`. 3273*912701f9SAndroid Build Coastguard Worker 1. Let `minpref` be the integer count of items in `matches`. 3274*912701f9SAndroid Build Coastguard Worker 1. For each tuple `tuple` of `sortable`: 3275*912701f9SAndroid Build Coastguard Worker 1. Let `matchpref` be an integer with the value `minpref`. 3276*912701f9SAndroid Build Coastguard Worker 1. Let `key` be the `tuple` _variant_ key at position `i`. 3277*912701f9SAndroid Build Coastguard Worker 1. If `key` is not the catch-all key `'*'`: 3278*912701f9SAndroid Build Coastguard Worker 1. Assert that `key` is a _literal_. 3279*912701f9SAndroid Build Coastguard Worker 1. Let `ks` be the resolved value of `key`. 3280*912701f9SAndroid Build Coastguard Worker 1. Let `matchpref` be the integer position of `ks` in `matches`. 3281*912701f9SAndroid Build Coastguard Worker 1. Set the `tuple` integer value as `matchpref`. 3282*912701f9SAndroid Build Coastguard Worker 1. Set `sortable` to be the result of calling the method `SortVariants(sortable)`. 3283*912701f9SAndroid Build Coastguard Worker 1. Set `i` to be `i` - 1. 3284*912701f9SAndroid Build Coastguard Worker1. Let `var` be the _variant_ element of the first element of `sortable`. 3285*912701f9SAndroid Build Coastguard Worker1. Select the _pattern_ of `var`. 3286*912701f9SAndroid Build Coastguard Worker 3287*912701f9SAndroid Build Coastguard Worker`SortVariants` is a method whose single argument is 3288*912701f9SAndroid Build Coastguard Workera list of (integer, _variant_) tuples. 3289*912701f9SAndroid Build Coastguard WorkerIt returns a list of (integer, _variant_) tuples. 3290*912701f9SAndroid Build Coastguard WorkerAny implementation of `SortVariants` is acceptable 3291*912701f9SAndroid Build Coastguard Workeras long as it satisfies the following requirements: 3292*912701f9SAndroid Build Coastguard Worker 3293*912701f9SAndroid Build Coastguard Worker1. Let `sortable` be an arbitrary list of (integer, _variant_) tuples. 3294*912701f9SAndroid Build Coastguard Worker1. Let `sorted` be `SortVariants(sortable)`. 3295*912701f9SAndroid Build Coastguard Worker1. `sorted` is the result of sorting `sortable` using the following comparator: 3296*912701f9SAndroid Build Coastguard Worker 1. `(i1, v1)` <= `(i2, v2)` if and only if `i1 <= i2`. 3297*912701f9SAndroid Build Coastguard Worker1. The sort is stable (pairs of tuples from `sortable` that are equal 3298*912701f9SAndroid Build Coastguard Worker in their first element have the same relative order in `sorted`). 3299*912701f9SAndroid Build Coastguard Worker 3300*912701f9SAndroid Build Coastguard Worker#### Examples 3301*912701f9SAndroid Build Coastguard Worker 3302*912701f9SAndroid Build Coastguard Worker_This section is non-normative._ 3303*912701f9SAndroid Build Coastguard Worker 3304*912701f9SAndroid Build Coastguard Worker##### Example 1 3305*912701f9SAndroid Build Coastguard Worker 3306*912701f9SAndroid Build Coastguard WorkerPresuming a minimal implementation which only supports `:string` annotation 3307*912701f9SAndroid Build Coastguard Workerwhich matches keys by using string comparison, 3308*912701f9SAndroid Build Coastguard Workerand a formatting context in which 3309*912701f9SAndroid Build Coastguard Workerthe variable reference `$foo` resolves to the string `'foo'` and 3310*912701f9SAndroid Build Coastguard Workerthe variable reference `$bar` resolves to the string `'bar'`, 3311*912701f9SAndroid Build Coastguard Workerpattern selection proceeds as follows for this message: 3312*912701f9SAndroid Build Coastguard Worker 3313*912701f9SAndroid Build Coastguard Worker``` 3314*912701f9SAndroid Build Coastguard Worker.match {$foo :string} {$bar :string} 3315*912701f9SAndroid Build Coastguard Workerbar bar {{All bar}} 3316*912701f9SAndroid Build Coastguard Workerfoo foo {{All foo}} 3317*912701f9SAndroid Build Coastguard Worker* * {{Otherwise}} 3318*912701f9SAndroid Build Coastguard Worker``` 3319*912701f9SAndroid Build Coastguard Worker 3320*912701f9SAndroid Build Coastguard Worker1. For the first selector:<br> 3321*912701f9SAndroid Build Coastguard Worker The value of the selector is resolved to be `'foo'`.<br> 3322*912701f9SAndroid Build Coastguard Worker The available keys « `'bar'`, `'foo'` » are compared to `'foo'`,<br> 3323*912701f9SAndroid Build Coastguard Worker resulting in a list « `'foo'` » of matching keys. 3324*912701f9SAndroid Build Coastguard Worker 3325*912701f9SAndroid Build Coastguard Worker2. For the second selector:<br> 3326*912701f9SAndroid Build Coastguard Worker The value of the selector is resolved to be `'bar'`.<br> 3327*912701f9SAndroid Build Coastguard Worker The available keys « `'bar'`, `'foo'` » are compared to `'bar'`,<br> 3328*912701f9SAndroid Build Coastguard Worker resulting in a list « `'bar'` » of matching keys. 3329*912701f9SAndroid Build Coastguard Worker 3330*912701f9SAndroid Build Coastguard Worker3. Creating the list `vars` of variants matching all keys:<br> 3331*912701f9SAndroid Build Coastguard Worker The first variant `bar bar` is discarded as its first key does not match the first selector.<br> 3332*912701f9SAndroid Build Coastguard Worker The second variant `foo foo` is discarded as its second key does not match the second selector.<br> 3333*912701f9SAndroid Build Coastguard Worker The catch-all keys of the third variant `* *` always match, and this is added to `vars`,<br> 3334*912701f9SAndroid Build Coastguard Worker resulting in a list « `* *` » of variants. 3335*912701f9SAndroid Build Coastguard Worker 3336*912701f9SAndroid Build Coastguard Worker4. As the list `vars` only has one entry, it does not need to be sorted.<br> 3337*912701f9SAndroid Build Coastguard Worker The pattern `Otherwise` of the third variant is selected. 3338*912701f9SAndroid Build Coastguard Worker 3339*912701f9SAndroid Build Coastguard Worker##### Example 2 3340*912701f9SAndroid Build Coastguard Worker 3341*912701f9SAndroid Build Coastguard WorkerAlternatively, with the same implementation and formatting context as in Example 1, 3342*912701f9SAndroid Build Coastguard Workerpattern selection would proceed as follows for this message: 3343*912701f9SAndroid Build Coastguard Worker 3344*912701f9SAndroid Build Coastguard Worker``` 3345*912701f9SAndroid Build Coastguard Worker.match {$foo :string} {$bar :string} 3346*912701f9SAndroid Build Coastguard Worker* bar {{Any and bar}} 3347*912701f9SAndroid Build Coastguard Workerfoo * {{Foo and any}} 3348*912701f9SAndroid Build Coastguard Workerfoo bar {{Foo and bar}} 3349*912701f9SAndroid Build Coastguard Worker* * {{Otherwise}} 3350*912701f9SAndroid Build Coastguard Worker``` 3351*912701f9SAndroid Build Coastguard Worker 3352*912701f9SAndroid Build Coastguard Worker1. For the first selector:<br> 3353*912701f9SAndroid Build Coastguard Worker The value of the selector is resolved to be `'foo'`.<br> 3354*912701f9SAndroid Build Coastguard Worker The available keys « `'foo'` » are compared to `'foo'`,<br> 3355*912701f9SAndroid Build Coastguard Worker resulting in a list « `'foo'` » of matching keys. 3356*912701f9SAndroid Build Coastguard Worker 3357*912701f9SAndroid Build Coastguard Worker2. For the second selector:<br> 3358*912701f9SAndroid Build Coastguard Worker The value of the selector is resolved to be `'bar'`.<br> 3359*912701f9SAndroid Build Coastguard Worker The available keys « `'bar'` » are compared to `'bar'`,<br> 3360*912701f9SAndroid Build Coastguard Worker resulting in a list « `'bar'` » of matching keys. 3361*912701f9SAndroid Build Coastguard Worker 3362*912701f9SAndroid Build Coastguard Worker3. Creating the list `vars` of variants matching all keys:<br> 3363*912701f9SAndroid Build Coastguard Worker The keys of all variants either match each selector exactly, or via the catch-all key,<br> 3364*912701f9SAndroid Build Coastguard Worker resulting in a list « `* bar`, `foo *`, `foo bar`, `* *` » of variants. 3365*912701f9SAndroid Build Coastguard Worker 3366*912701f9SAndroid Build Coastguard Worker4. Sorting the variants:<br> 3367*912701f9SAndroid Build Coastguard Worker The list `sortable` is first set with the variants in their source order 3368*912701f9SAndroid Build Coastguard Worker and scores determined by the second selector:<br> 3369*912701f9SAndroid Build Coastguard Worker « ( 0, `* bar` ), ( 1, `foo *` ), ( 0, `foo bar` ), ( 1, `* *` ) »<br> 3370*912701f9SAndroid Build Coastguard Worker This is then sorted as:<br> 3371*912701f9SAndroid Build Coastguard Worker « ( 0, `* bar` ), ( 0, `foo bar` ), ( 1, `foo *` ), ( 1, `* *` ) ».<br> 3372*912701f9SAndroid Build Coastguard Worker To sort according to the first selector, the scores are updated to:<br> 3373*912701f9SAndroid Build Coastguard Worker « ( 1, `* bar` ), ( 0, `foo bar` ), ( 0, `foo *` ), ( 1, `* *` ) ».<br> 3374*912701f9SAndroid Build Coastguard Worker This is then sorted as:<br> 3375*912701f9SAndroid Build Coastguard Worker « ( 0, `foo bar` ), ( 0, `foo *` ), ( 1, `* bar` ), ( 1, `* *` ) ».<br> 3376*912701f9SAndroid Build Coastguard Worker 3377*912701f9SAndroid Build Coastguard Worker5. The pattern `Foo and bar` of the most preferred `foo bar` variant is selected. 3378*912701f9SAndroid Build Coastguard Worker 3379*912701f9SAndroid Build Coastguard Worker##### Example 3 3380*912701f9SAndroid Build Coastguard Worker 3381*912701f9SAndroid Build Coastguard WorkerA more-complex example is the matching found in selection APIs 3382*912701f9SAndroid Build Coastguard Workersuch as ICU's `PluralFormat`. 3383*912701f9SAndroid Build Coastguard WorkerSuppose that this API is represented here by the function `:number`. 3384*912701f9SAndroid Build Coastguard WorkerThis `:number` function can match a given numeric value to a specific number _literal_ 3385*912701f9SAndroid Build Coastguard Workerand **_also_** to a plural category (`zero`, `one`, `two`, `few`, `many`, `other`) 3386*912701f9SAndroid Build Coastguard Workeraccording to locale rules defined in CLDR. 3387*912701f9SAndroid Build Coastguard Worker 3388*912701f9SAndroid Build Coastguard WorkerGiven a variable reference `$count` whose value resolves to the number `1` 3389*912701f9SAndroid Build Coastguard Workerand an `en` (English) locale, 3390*912701f9SAndroid Build Coastguard Workerthe pattern selection proceeds as follows for this message: 3391*912701f9SAndroid Build Coastguard Worker 3392*912701f9SAndroid Build Coastguard Worker``` 3393*912701f9SAndroid Build Coastguard Worker.input {$count :number} 3394*912701f9SAndroid Build Coastguard Worker.match {$count} 3395*912701f9SAndroid Build Coastguard Workerone {{Category match for {$count}}} 3396*912701f9SAndroid Build Coastguard Worker1 {{Exact match for {$count}}} 3397*912701f9SAndroid Build Coastguard Worker* {{Other match for {$count}}} 3398*912701f9SAndroid Build Coastguard Worker``` 3399*912701f9SAndroid Build Coastguard Worker 3400*912701f9SAndroid Build Coastguard Worker1. For the selector:<br> 3401*912701f9SAndroid Build Coastguard Worker The value of the selector is resolved to an implementation-defined value 3402*912701f9SAndroid Build Coastguard Worker that is capable of performing English plural category selection on the value `1`.<br> 3403*912701f9SAndroid Build Coastguard Worker The available keys « `'one'`, `'1'` » are passed to 3404*912701f9SAndroid Build Coastguard Worker the implementation's MatchSelectorKeys method,<br> 3405*912701f9SAndroid Build Coastguard Worker resulting in a list « `'1'`, `'one'` » of matching keys. 3406*912701f9SAndroid Build Coastguard Worker 3407*912701f9SAndroid Build Coastguard Worker2. Creating the list `vars` of variants matching all keys:<br> 3408*912701f9SAndroid Build Coastguard Worker The keys of all variants are included in the list of matching keys, or use the catch-all key,<br> 3409*912701f9SAndroid Build Coastguard Worker resulting in a list « `one`, `1`, `*` » of variants. 3410*912701f9SAndroid Build Coastguard Worker 3411*912701f9SAndroid Build Coastguard Worker3. Sorting the variants:<br> 3412*912701f9SAndroid Build Coastguard Worker The list `sortable` is first set with the variants in their source order 3413*912701f9SAndroid Build Coastguard Worker and scores determined by the selector key order:<br> 3414*912701f9SAndroid Build Coastguard Worker « ( 1, `one` ), ( 0, `1` ), ( 2, `*` ) »<br> 3415*912701f9SAndroid Build Coastguard Worker This is then sorted as:<br> 3416*912701f9SAndroid Build Coastguard Worker « ( 0, `1` ), ( 1, `one` ), ( 2, `*` ) »<br> 3417*912701f9SAndroid Build Coastguard Worker 3418*912701f9SAndroid Build Coastguard Worker4. The pattern `Exact match for {$count}` of the most preferred `1` variant is selected. 3419*912701f9SAndroid Build Coastguard Worker 3420*912701f9SAndroid Build Coastguard Worker### Formatting 3421*912701f9SAndroid Build Coastguard Worker 3422*912701f9SAndroid Build Coastguard WorkerAfter _pattern selection_, 3423*912701f9SAndroid Build Coastguard Workereach _text_ and _placeholder_ part of the selected _pattern_ is resolved and formatted. 3424*912701f9SAndroid Build Coastguard Worker 3425*912701f9SAndroid Build Coastguard WorkerResolved values cannot always be formatted by a given implementation. 3426*912701f9SAndroid Build Coastguard WorkerWhen such an error occurs during _formatting_, 3427*912701f9SAndroid Build Coastguard Workeran implementation SHOULD emit a _Formatting Error_ and produce a 3428*912701f9SAndroid Build Coastguard Worker_fallback value_ for the _placeholder_ that produced the error. 3429*912701f9SAndroid Build Coastguard WorkerA formatting function MAY substitute a value to use instead of a _fallback value_. 3430*912701f9SAndroid Build Coastguard Worker 3431*912701f9SAndroid Build Coastguard WorkerImplementations MAY represent the result of _formatting_ using the most 3432*912701f9SAndroid Build Coastguard Workerappropriate data type or structure. Some examples of these include: 3433*912701f9SAndroid Build Coastguard Worker 3434*912701f9SAndroid Build Coastguard Worker- A single string concatenated from the parts of the resolved _pattern_. 3435*912701f9SAndroid Build Coastguard Worker- A string with associated attributes for portions of its text. 3436*912701f9SAndroid Build Coastguard Worker- A flat sequence of objects corresponding to each resolved value. 3437*912701f9SAndroid Build Coastguard Worker- A hierarchical structure of objects that group spans of resolved values, 3438*912701f9SAndroid Build Coastguard Worker such as sequences delimited by _markup-open_ and _markup-close_ _placeholders_. 3439*912701f9SAndroid Build Coastguard Worker 3440*912701f9SAndroid Build Coastguard WorkerImplementations SHOULD provide _formatting_ result types that match user needs, 3441*912701f9SAndroid Build Coastguard Workerincluding situations that require further processing of formatted messages. 3442*912701f9SAndroid Build Coastguard WorkerImplementations SHOULD encourage users to consider a formatted localised string 3443*912701f9SAndroid Build Coastguard Workeras an opaque data structure, suitable only for presentation. 3444*912701f9SAndroid Build Coastguard Worker 3445*912701f9SAndroid Build Coastguard WorkerWhen formatting to a string, the default representation of all _markup_ 3446*912701f9SAndroid Build Coastguard WorkerMUST be an empty string. 3447*912701f9SAndroid Build Coastguard WorkerImplementations MAY offer functionality for customizing this, 3448*912701f9SAndroid Build Coastguard Workersuch as by emitting XML-ish tags for each _markup_. 3449*912701f9SAndroid Build Coastguard Worker 3450*912701f9SAndroid Build Coastguard Worker_Attributes_ are reserved for future standardization. 3451*912701f9SAndroid Build Coastguard WorkerOther than checking for valid syntax, they SHOULD NOT 3452*912701f9SAndroid Build Coastguard Workeraffect the processing or output of a _message_. 3453*912701f9SAndroid Build Coastguard Worker 3454*912701f9SAndroid Build Coastguard Worker#### Examples 3455*912701f9SAndroid Build Coastguard Worker 3456*912701f9SAndroid Build Coastguard Worker_This section is non-normative._ 3457*912701f9SAndroid Build Coastguard Worker 3458*912701f9SAndroid Build Coastguard Worker1. An implementation might choose to return an interstitial object 3459*912701f9SAndroid Build Coastguard Worker so that the caller can "decorate" portions of the formatted value. 3460*912701f9SAndroid Build Coastguard Worker In ICU4J, the `NumberFormatter` class returns a `FormattedNumber` object, 3461*912701f9SAndroid Build Coastguard Worker so a _pattern_ such as `This is my number {42 :number}` might return 3462*912701f9SAndroid Build Coastguard Worker the character sequence `This is my number ` 3463*912701f9SAndroid Build Coastguard Worker followed by a `FormattedNumber` object representing the value `42` in the current locale. 3464*912701f9SAndroid Build Coastguard Worker 3465*912701f9SAndroid Build Coastguard Worker2. A formatter in a web browser could format a message as a DOM fragment 3466*912701f9SAndroid Build Coastguard Worker rather than as a representation of its HTML source. 3467*912701f9SAndroid Build Coastguard Worker 3468*912701f9SAndroid Build Coastguard Worker#### Formatting Fallback Values 3469*912701f9SAndroid Build Coastguard Worker 3470*912701f9SAndroid Build Coastguard WorkerIf the resolved _pattern_ includes any _fallback values_ 3471*912701f9SAndroid Build Coastguard Workerand the formatting result is a concatenated string or a sequence of strings, 3472*912701f9SAndroid Build Coastguard Workerthe string representation of each _fallback value_ MUST be the concatenation of 3473*912701f9SAndroid Build Coastguard Workera U+007B LEFT CURLY BRACKET `{`, 3474*912701f9SAndroid Build Coastguard Workerthe _fallback value_ as a string, 3475*912701f9SAndroid Build Coastguard Workerand a U+007D RIGHT CURLY BRACKET `}`. 3476*912701f9SAndroid Build Coastguard Worker 3477*912701f9SAndroid Build Coastguard Worker> For example, 3478*912701f9SAndroid Build Coastguard Worker> a message with a _Syntax Error_ and no fallback string 3479*912701f9SAndroid Build Coastguard Worker> defined in the _formatting context_ would format to a string as `{�}`. 3480*912701f9SAndroid Build Coastguard Worker 3481*912701f9SAndroid Build Coastguard Worker#### Handling Bidirectional Text 3482*912701f9SAndroid Build Coastguard Worker 3483*912701f9SAndroid Build Coastguard Worker_Messages_ contain text. Any text can be 3484*912701f9SAndroid Build Coastguard Worker[bidirectional text](https://www.w3.org/TR/i18n-glossary/#dfn-bidirectional-text). 3485*912701f9SAndroid Build Coastguard WorkerThat is, the text can can consist of a mixture of left-to-right and right-to-left spans of text. 3486*912701f9SAndroid Build Coastguard WorkerThe display of bidirectional text is defined by the 3487*912701f9SAndroid Build Coastguard Worker[Unicode Bidirectional Algorithm](http://www.unicode.org/reports/tr9/) [UAX9]. 3488*912701f9SAndroid Build Coastguard Worker 3489*912701f9SAndroid Build Coastguard WorkerThe directionality of the message as a whole is provided by the _formatting context_. 3490*912701f9SAndroid Build Coastguard Worker 3491*912701f9SAndroid Build Coastguard WorkerWhen a _message_ is formatted, _placeholders_ are replaced 3492*912701f9SAndroid Build Coastguard Workerwith their formatted representation. 3493*912701f9SAndroid Build Coastguard WorkerApplying the Unicode Bidirectional Algorithm to the text of a formatted _message_ 3494*912701f9SAndroid Build Coastguard Worker(including its formatted parts) 3495*912701f9SAndroid Build Coastguard Workercan result in unexpected or undesirable 3496*912701f9SAndroid Build Coastguard Worker[spillover effects](https://www.w3.org/TR/i18n-glossary/#dfn-spillover-effects). 3497*912701f9SAndroid Build Coastguard WorkerApplying [bidi isolation](https://www.w3.org/TR/i18n-glossary/#dfn-bidi-isolation) 3498*912701f9SAndroid Build Coastguard Workerto each affected formatted value helps avoid this spillover in a formatted _message_. 3499*912701f9SAndroid Build Coastguard Worker 3500*912701f9SAndroid Build Coastguard WorkerNote that both the _message_ and, separately, each _placeholder_ need to have 3501*912701f9SAndroid Build Coastguard Workerdirection metadata for this to work. 3502*912701f9SAndroid Build Coastguard WorkerIf an implementation supports formatting to something other than a string 3503*912701f9SAndroid Build Coastguard Worker(such as a sequence of parts), 3504*912701f9SAndroid Build Coastguard Workerthe directionality of each formatted _placeholder_ needs to be available to the caller. 3505*912701f9SAndroid Build Coastguard Worker 3506*912701f9SAndroid Build Coastguard WorkerIf a formatted _expression_ itself contains spans with differing directionality, 3507*912701f9SAndroid Build Coastguard Workerits formatter SHOULD perform any necessary processing, such as inserting controls or 3508*912701f9SAndroid Build Coastguard Workerisolating such parts to ensure that the formatted value displays correctly in a plain text context. 3509*912701f9SAndroid Build Coastguard Worker 3510*912701f9SAndroid Build Coastguard Worker> For example, an implementation could provide a `:currency` formatting function 3511*912701f9SAndroid Build Coastguard Worker> which inserts strongly directional characters, such as U+200F RIGHT-TO-LEFT MARK (RLM), 3512*912701f9SAndroid Build Coastguard Worker> U+200E LEFT-TO-RIGHT MARK (LRM), or U+061C ARABIC LETTER MARKER (ALM), 3513*912701f9SAndroid Build Coastguard Worker> to coerce proper display of the sign and currency symbol next to a formatted number. 3514*912701f9SAndroid Build Coastguard Worker> An example of this is formatting the value `-1234.56` as the currency `AED` 3515*912701f9SAndroid Build Coastguard Worker> in the `ar-AE` locale. The formatted value appears like this: 3516*912701f9SAndroid Build Coastguard Worker> ``` 3517*912701f9SAndroid Build Coastguard Worker> -1,234.56 د.إ. 3518*912701f9SAndroid Build Coastguard Worker> ``` 3519*912701f9SAndroid Build Coastguard Worker> The code point sequence for this string, as produced by the ICU4J `NumberFormat` function, 3520*912701f9SAndroid Build Coastguard Worker> includes **U+200F U+200E** at the start and **U+200F** at the end of the string. 3521*912701f9SAndroid Build Coastguard Worker> If it did not do this, the same string would appear like this instead: 3522*912701f9SAndroid Build Coastguard Worker> 3523*912701f9SAndroid Build Coastguard Worker>  3524*912701f9SAndroid Build Coastguard Worker 3525*912701f9SAndroid Build Coastguard WorkerA **_bidirectional isolation strategy_** is functionality in the formatter's 3526*912701f9SAndroid Build Coastguard Workerprocessing of a _message_ that produces bidirectional output text that is ready for display. 3527*912701f9SAndroid Build Coastguard Worker 3528*912701f9SAndroid Build Coastguard WorkerThe **_Default Bidi Strategy_** is a _bidirectional isolation strategy_ that uses 3529*912701f9SAndroid Build Coastguard Workerisolating Unicode control characters around _placeholder_'s formatted values. 3530*912701f9SAndroid Build Coastguard WorkerIt is primarily intended for use in plain-text strings, where markup or other mechanisms 3531*912701f9SAndroid Build Coastguard Workerare not available. 3532*912701f9SAndroid Build Coastguard WorkerImplementations MUST provide the _Default Bidi Strategy_ as one of the 3533*912701f9SAndroid Build Coastguard Worker_bidirectional isolation strategies_. 3534*912701f9SAndroid Build Coastguard Worker 3535*912701f9SAndroid Build Coastguard WorkerImplementations MAY provide other _bidirectional isolation strategies_. 3536*912701f9SAndroid Build Coastguard Worker 3537*912701f9SAndroid Build Coastguard WorkerImplementations MAY supply a _bidirectional isolation strategy_ that performs no processing. 3538*912701f9SAndroid Build Coastguard Worker 3539*912701f9SAndroid Build Coastguard WorkerThe _Default Bidi Strategy_ is defined as follows: 3540*912701f9SAndroid Build Coastguard Worker 3541*912701f9SAndroid Build Coastguard Worker1. Let `msgdir` be the directionality of the whole message, 3542*912701f9SAndroid Build Coastguard Worker one of « `'LTR'`, `'RTL'`, `'unknown'` ». 3543*912701f9SAndroid Build Coastguard Worker These correspond to the message having left-to-right directionality, 3544*912701f9SAndroid Build Coastguard Worker right-to-left directionality, and to the message's directionality not being known. 3545*912701f9SAndroid Build Coastguard Worker1. For each _expression_ `exp` in _pattern_: 3546*912701f9SAndroid Build Coastguard Worker 1. Let `fmt` be the formatted string representation of the resolved value of `exp`. 3547*912701f9SAndroid Build Coastguard Worker 1. Let `dir` be the directionality of `fmt`, 3548*912701f9SAndroid Build Coastguard Worker one of « `'LTR'`, `'RTL'`, `'unknown'` », with the same meanings as for `msgdir`. 3549*912701f9SAndroid Build Coastguard Worker 1. If `dir` is `'LTR'`: 3550*912701f9SAndroid Build Coastguard Worker 1. If `msgdir` is `'LTR'` 3551*912701f9SAndroid Build Coastguard Worker in the formatted output, let `fmt` be itself 3552*912701f9SAndroid Build Coastguard Worker 1. Else, in the formatted output, 3553*912701f9SAndroid Build Coastguard Worker prefix `fmt` with U+2066 LEFT-TO-RIGHT ISOLATE 3554*912701f9SAndroid Build Coastguard Worker and postfix it with U+2069 POP DIRECTIONAL ISOLATE. 3555*912701f9SAndroid Build Coastguard Worker 1. Else, if `dir` is `'RTL'`: 3556*912701f9SAndroid Build Coastguard Worker 1. In the formatted output, 3557*912701f9SAndroid Build Coastguard Worker prefix `fmt` with U+2067 RIGHT-TO-LEFT ISOLATE 3558*912701f9SAndroid Build Coastguard Worker and postfix it with U+2069 POP DIRECTIONAL ISOLATE. 3559*912701f9SAndroid Build Coastguard Worker 1. Else: 3560*912701f9SAndroid Build Coastguard Worker 1. In the formatted output, 3561*912701f9SAndroid Build Coastguard Worker prefix `fmt` with U+2068 FIRST STRONG ISOLATE 3562*912701f9SAndroid Build Coastguard Worker and postfix it with U+2069 POP DIRECTIONAL ISOLATE. 3563*912701f9SAndroid Build Coastguard Worker 3564*912701f9SAndroid Build Coastguard Worker 3565*912701f9SAndroid Build Coastguard Worker## Interchange Data Model 3566*912701f9SAndroid Build Coastguard Worker 3567*912701f9SAndroid Build Coastguard WorkerThis section defines a data model representation of MessageFormat 2 _messages_. 3568*912701f9SAndroid Build Coastguard Worker 3569*912701f9SAndroid Build Coastguard WorkerImplementations are not required to use this data model for their internal representation of messages. 3570*912701f9SAndroid Build Coastguard WorkerNeither are they required to provide an interface that accepts or produces 3571*912701f9SAndroid Build Coastguard Workerrepresentations of this data model. 3572*912701f9SAndroid Build Coastguard Worker 3573*912701f9SAndroid Build Coastguard WorkerThe major reason this specification provides a data model is to allow interchange of 3574*912701f9SAndroid Build Coastguard Workerthe logical representation of a _message_ between different implementations. 3575*912701f9SAndroid Build Coastguard WorkerThis includes mapping legacy formatting syntaxes (such as MessageFormat 1) 3576*912701f9SAndroid Build Coastguard Workerto a MessageFormat 2 implementation. 3577*912701f9SAndroid Build Coastguard WorkerAnother use would be in converting to or from translation formats without 3578*912701f9SAndroid Build Coastguard Workerthe need to continually parse and serialize all or part of a message. 3579*912701f9SAndroid Build Coastguard Worker 3580*912701f9SAndroid Build Coastguard WorkerImplementations that expose APIs supporting the production, consumption, or transformation of a 3581*912701f9SAndroid Build Coastguard Worker_message_ as a data structure are encouraged to use this data model. 3582*912701f9SAndroid Build Coastguard Worker 3583*912701f9SAndroid Build Coastguard WorkerThis data model provides these capabilities: 3584*912701f9SAndroid Build Coastguard Worker- any MessageFormat 2 message (including future versions) 3585*912701f9SAndroid Build Coastguard Worker can be parsed into this representation 3586*912701f9SAndroid Build Coastguard Worker- this data model representation can be serialized as a well-formed 3587*912701f9SAndroid Build Coastguard WorkerMessageFormat 2 message 3588*912701f9SAndroid Build Coastguard Worker- parsing a MessageFormat 2 message into a data model representation 3589*912701f9SAndroid Build Coastguard Worker and then serializing it results in an equivalently functional message 3590*912701f9SAndroid Build Coastguard Worker 3591*912701f9SAndroid Build Coastguard WorkerThis data model might also be used to: 3592*912701f9SAndroid Build Coastguard Worker- parse a non-MessageFormat 2 message into a data model 3593*912701f9SAndroid Build Coastguard Worker (and therefore re-serialize it as MessageFormat 2). 3594*912701f9SAndroid Build Coastguard Worker Note that this depends on compatibility between the two syntaxes. 3595*912701f9SAndroid Build Coastguard Worker- re-serialize a MessageFormat 2 message into some other format 3596*912701f9SAndroid Build Coastguard Worker including (but not limited to) other formatting syntaxes 3597*912701f9SAndroid Build Coastguard Worker or translation formats. 3598*912701f9SAndroid Build Coastguard Worker 3599*912701f9SAndroid Build Coastguard WorkerTo ensure compatibility across all platforms, 3600*912701f9SAndroid Build Coastguard Workerthis interchange data model is defined here using TypeScript notation. 3601*912701f9SAndroid Build Coastguard WorkerTwo equivalent definitions of the data model are also provided: 3602*912701f9SAndroid Build Coastguard Worker 3603*912701f9SAndroid Build Coastguard Worker- `common/dtd/messageFormat/message.json` is a JSON Schema definition, 3604*912701f9SAndroid Build Coastguard Worker for use with message data encoded as JSON or compatible formats, such as YAML. 3605*912701f9SAndroid Build Coastguard Worker- `common/dtd/messageFormat/message.json` is a document type definition (DTD), 3606*912701f9SAndroid Build Coastguard Worker for use with message data encoded as XML. 3607*912701f9SAndroid Build Coastguard Worker 3608*912701f9SAndroid Build Coastguard WorkerNote that while the data model description below is the canonical one, 3609*912701f9SAndroid Build Coastguard Workerthe JSON and DTD definitions are intended for interchange between systems and processors. 3610*912701f9SAndroid Build Coastguard WorkerTo that end, they relax some aspects of the data model, such as allowing 3611*912701f9SAndroid Build Coastguard Workerdeclarations, options, and attributes to be optional rather than required properties. 3612*912701f9SAndroid Build Coastguard Worker 3613*912701f9SAndroid Build Coastguard Worker> [!NOTE] 3614*912701f9SAndroid Build Coastguard Worker> Users relying on XML representations of messages should note that 3615*912701f9SAndroid Build Coastguard Worker> XML 1.0 does not allow for the representation of all C0 control characters (U+0000-U+001F). 3616*912701f9SAndroid Build Coastguard Worker> Except for U+0000 NULL , these characters are allowed in MessageFormat 2 messages, 3617*912701f9SAndroid Build Coastguard Worker> so systems and users relying on this XML representation for interchange 3618*912701f9SAndroid Build Coastguard Worker> might need to supply an alternate escape mechanism to support messages 3619*912701f9SAndroid Build Coastguard Worker> that contain these characters. 3620*912701f9SAndroid Build Coastguard Worker 3621*912701f9SAndroid Build Coastguard Worker> [!IMPORTANT] 3622*912701f9SAndroid Build Coastguard Worker> The data model uses the field name `name` to denote various interface identifiers. 3623*912701f9SAndroid Build Coastguard Worker> In the MessageFormat 2 [syntax](#syntax), the source for these `name` fields 3624*912701f9SAndroid Build Coastguard Worker> sometimes uses the production `identifier`. 3625*912701f9SAndroid Build Coastguard Worker> This happens when the named item, such as a _function_, supports namespacing. 3626*912701f9SAndroid Build Coastguard Worker> 3627*912701f9SAndroid Build Coastguard Worker> In the Tech Preview, feedback on whether to separate the `namespace` from the `name` 3628*912701f9SAndroid Build Coastguard Worker> and represent both separately, or just, as here, use an opaque single field `name` 3629*912701f9SAndroid Build Coastguard Worker> is desired. 3630*912701f9SAndroid Build Coastguard Worker 3631*912701f9SAndroid Build Coastguard Worker### Messages 3632*912701f9SAndroid Build Coastguard Worker 3633*912701f9SAndroid Build Coastguard WorkerA `SelectMessage` corresponds to a syntax message that includes _selectors_. 3634*912701f9SAndroid Build Coastguard WorkerA message without _selectors_ and with a single _pattern_ is represented by a `PatternMessage`. 3635*912701f9SAndroid Build Coastguard Worker 3636*912701f9SAndroid Build Coastguard WorkerIn the syntax, 3637*912701f9SAndroid Build Coastguard Workera `PatternMessage` may be represented either as a _simple message_ or as a _complex message_, 3638*912701f9SAndroid Build Coastguard Workerdepending on whether it has declarations and if its `pattern` is allowed in a _simple message_. 3639*912701f9SAndroid Build Coastguard Worker 3640*912701f9SAndroid Build Coastguard Worker```ts 3641*912701f9SAndroid Build Coastguard Workertype Message = PatternMessage | SelectMessage; 3642*912701f9SAndroid Build Coastguard Worker 3643*912701f9SAndroid Build Coastguard Workerinterface PatternMessage { 3644*912701f9SAndroid Build Coastguard Worker type: "message"; 3645*912701f9SAndroid Build Coastguard Worker declarations: Declaration[]; 3646*912701f9SAndroid Build Coastguard Worker pattern: Pattern; 3647*912701f9SAndroid Build Coastguard Worker} 3648*912701f9SAndroid Build Coastguard Worker 3649*912701f9SAndroid Build Coastguard Workerinterface SelectMessage { 3650*912701f9SAndroid Build Coastguard Worker type: "select"; 3651*912701f9SAndroid Build Coastguard Worker declarations: Declaration[]; 3652*912701f9SAndroid Build Coastguard Worker selectors: Expression[]; 3653*912701f9SAndroid Build Coastguard Worker variants: Variant[]; 3654*912701f9SAndroid Build Coastguard Worker} 3655*912701f9SAndroid Build Coastguard Worker``` 3656*912701f9SAndroid Build Coastguard Worker 3657*912701f9SAndroid Build Coastguard WorkerEach message _declaration_ is represented by a `Declaration`, 3658*912701f9SAndroid Build Coastguard Workerwhich connects the `name` of a _variable_ 3659*912701f9SAndroid Build Coastguard Workerwith its _expression_ `value`. 3660*912701f9SAndroid Build Coastguard WorkerThe `name` does not include the initial `$` of the _variable_. 3661*912701f9SAndroid Build Coastguard Worker 3662*912701f9SAndroid Build Coastguard WorkerThe `name` of an `InputDeclaration` MUST be the same 3663*912701f9SAndroid Build Coastguard Workeras the `name` in the `VariableRef` of its `VariableExpression` `value`. 3664*912701f9SAndroid Build Coastguard Worker 3665*912701f9SAndroid Build Coastguard WorkerAn `UnsupportedStatement` represents a statement not supported by the implementation. 3666*912701f9SAndroid Build Coastguard WorkerIts `keyword` is a non-empty string name (i.e. not including the initial `.`). 3667*912701f9SAndroid Build Coastguard WorkerIf not empty, the `body` is the "raw" value (i.e. escape sequences are not processed) 3668*912701f9SAndroid Build Coastguard Workerstarting after the keyword and up to the first _expression_, 3669*912701f9SAndroid Build Coastguard Workernot including leading or trailing whitespace. 3670*912701f9SAndroid Build Coastguard WorkerThe non-empty `expressions` correspond to the trailing _expressions_ of the _reserved statement_. 3671*912701f9SAndroid Build Coastguard Worker 3672*912701f9SAndroid Build Coastguard Worker> [!NOTE] 3673*912701f9SAndroid Build Coastguard Worker> Be aware that future versions of this specification 3674*912701f9SAndroid Build Coastguard Worker> might assign meaning to _reserved statement_ values. 3675*912701f9SAndroid Build Coastguard Worker> This would result in new interfaces being added to 3676*912701f9SAndroid Build Coastguard Worker> this data model. 3677*912701f9SAndroid Build Coastguard Worker 3678*912701f9SAndroid Build Coastguard Worker```ts 3679*912701f9SAndroid Build Coastguard Workertype Declaration = InputDeclaration | LocalDeclaration | UnsupportedStatement; 3680*912701f9SAndroid Build Coastguard Worker 3681*912701f9SAndroid Build Coastguard Workerinterface InputDeclaration { 3682*912701f9SAndroid Build Coastguard Worker type: "input"; 3683*912701f9SAndroid Build Coastguard Worker name: string; 3684*912701f9SAndroid Build Coastguard Worker value: VariableExpression; 3685*912701f9SAndroid Build Coastguard Worker} 3686*912701f9SAndroid Build Coastguard Worker 3687*912701f9SAndroid Build Coastguard Workerinterface LocalDeclaration { 3688*912701f9SAndroid Build Coastguard Worker type: "local"; 3689*912701f9SAndroid Build Coastguard Worker name: string; 3690*912701f9SAndroid Build Coastguard Worker value: Expression; 3691*912701f9SAndroid Build Coastguard Worker} 3692*912701f9SAndroid Build Coastguard Worker 3693*912701f9SAndroid Build Coastguard Workerinterface UnsupportedStatement { 3694*912701f9SAndroid Build Coastguard Worker type: "unsupported-statement"; 3695*912701f9SAndroid Build Coastguard Worker keyword: string; 3696*912701f9SAndroid Build Coastguard Worker body?: string; 3697*912701f9SAndroid Build Coastguard Worker expressions: Expression[]; 3698*912701f9SAndroid Build Coastguard Worker} 3699*912701f9SAndroid Build Coastguard Worker``` 3700*912701f9SAndroid Build Coastguard Worker 3701*912701f9SAndroid Build Coastguard WorkerIn a `SelectMessage`, 3702*912701f9SAndroid Build Coastguard Workerthe `keys` and `value` of each _variant_ are represented as an array of `Variant`. 3703*912701f9SAndroid Build Coastguard WorkerFor the `CatchallKey`, a string `value` may be provided to retain an identifier. 3704*912701f9SAndroid Build Coastguard WorkerThis is always `'*'` in MessageFormat 2 syntax, but may vary in other formats. 3705*912701f9SAndroid Build Coastguard Worker 3706*912701f9SAndroid Build Coastguard Worker```ts 3707*912701f9SAndroid Build Coastguard Workerinterface Variant { 3708*912701f9SAndroid Build Coastguard Worker keys: Array<Literal | CatchallKey>; 3709*912701f9SAndroid Build Coastguard Worker value: Pattern; 3710*912701f9SAndroid Build Coastguard Worker} 3711*912701f9SAndroid Build Coastguard Worker 3712*912701f9SAndroid Build Coastguard Workerinterface CatchallKey { 3713*912701f9SAndroid Build Coastguard Worker type: "*"; 3714*912701f9SAndroid Build Coastguard Worker value?: string; 3715*912701f9SAndroid Build Coastguard Worker} 3716*912701f9SAndroid Build Coastguard Worker``` 3717*912701f9SAndroid Build Coastguard Worker 3718*912701f9SAndroid Build Coastguard Worker### Patterns 3719*912701f9SAndroid Build Coastguard Worker 3720*912701f9SAndroid Build Coastguard WorkerEach `Pattern` contains a linear sequence of text and placeholders corresponding to potential output of a message. 3721*912701f9SAndroid Build Coastguard Worker 3722*912701f9SAndroid Build Coastguard WorkerEach element of the `Pattern` MUST either be a non-empty string, an `Expression`, or a `Markup` object. 3723*912701f9SAndroid Build Coastguard WorkerString values represent literal _text_. 3724*912701f9SAndroid Build Coastguard WorkerString values include all processing of the underlying _text_ values, 3725*912701f9SAndroid Build Coastguard Workerincluding escape sequence processing. 3726*912701f9SAndroid Build Coastguard Worker`Expression` wraps each of the potential _expression_ shapes. 3727*912701f9SAndroid Build Coastguard Worker`Markup` wraps each of the potential _markup_ shapes. 3728*912701f9SAndroid Build Coastguard Worker 3729*912701f9SAndroid Build Coastguard WorkerImplementations MUST NOT rely on the set of `Expression` and 3730*912701f9SAndroid Build Coastguard Worker`Markup` interfaces defined in this document being exhaustive. 3731*912701f9SAndroid Build Coastguard WorkerFuture versions of this specification might define additional 3732*912701f9SAndroid Build Coastguard Workerexpressions or markup. 3733*912701f9SAndroid Build Coastguard Worker 3734*912701f9SAndroid Build Coastguard Worker```ts 3735*912701f9SAndroid Build Coastguard Workertype Pattern = Array<string | Expression | Markup>; 3736*912701f9SAndroid Build Coastguard Worker 3737*912701f9SAndroid Build Coastguard Workertype Expression = 3738*912701f9SAndroid Build Coastguard Worker | LiteralExpression 3739*912701f9SAndroid Build Coastguard Worker | VariableExpression 3740*912701f9SAndroid Build Coastguard Worker | FunctionExpression 3741*912701f9SAndroid Build Coastguard Worker | UnsupportedExpression; 3742*912701f9SAndroid Build Coastguard Worker 3743*912701f9SAndroid Build Coastguard Workerinterface LiteralExpression { 3744*912701f9SAndroid Build Coastguard Worker type: "expression"; 3745*912701f9SAndroid Build Coastguard Worker arg: Literal; 3746*912701f9SAndroid Build Coastguard Worker annotation?: FunctionAnnotation | UnsupportedAnnotation; 3747*912701f9SAndroid Build Coastguard Worker attributes: Attribute[]; 3748*912701f9SAndroid Build Coastguard Worker} 3749*912701f9SAndroid Build Coastguard Worker 3750*912701f9SAndroid Build Coastguard Workerinterface VariableExpression { 3751*912701f9SAndroid Build Coastguard Worker type: "expression"; 3752*912701f9SAndroid Build Coastguard Worker arg: VariableRef; 3753*912701f9SAndroid Build Coastguard Worker annotation?: FunctionAnnotation | UnsupportedAnnotation; 3754*912701f9SAndroid Build Coastguard Worker attributes: Attribute[]; 3755*912701f9SAndroid Build Coastguard Worker} 3756*912701f9SAndroid Build Coastguard Worker 3757*912701f9SAndroid Build Coastguard Workerinterface FunctionExpression { 3758*912701f9SAndroid Build Coastguard Worker type: "expression"; 3759*912701f9SAndroid Build Coastguard Worker arg?: never; 3760*912701f9SAndroid Build Coastguard Worker annotation: FunctionAnnotation; 3761*912701f9SAndroid Build Coastguard Worker attributes: Attribute[]; 3762*912701f9SAndroid Build Coastguard Worker} 3763*912701f9SAndroid Build Coastguard Worker 3764*912701f9SAndroid Build Coastguard Workerinterface UnsupportedExpression { 3765*912701f9SAndroid Build Coastguard Worker type: "expression"; 3766*912701f9SAndroid Build Coastguard Worker arg?: never; 3767*912701f9SAndroid Build Coastguard Worker annotation: UnsupportedAnnotation; 3768*912701f9SAndroid Build Coastguard Worker attributes: Attribute[]; 3769*912701f9SAndroid Build Coastguard Worker} 3770*912701f9SAndroid Build Coastguard Worker 3771*912701f9SAndroid Build Coastguard Workerinterface Attribute { 3772*912701f9SAndroid Build Coastguard Worker name: string; 3773*912701f9SAndroid Build Coastguard Worker value?: Literal | VariableRef; 3774*912701f9SAndroid Build Coastguard Worker} 3775*912701f9SAndroid Build Coastguard Worker``` 3776*912701f9SAndroid Build Coastguard Worker 3777*912701f9SAndroid Build Coastguard Worker### Expressions 3778*912701f9SAndroid Build Coastguard Worker 3779*912701f9SAndroid Build Coastguard WorkerThe `Literal` and `VariableRef` correspond to the the _literal_ and _variable_ syntax rules. 3780*912701f9SAndroid Build Coastguard WorkerWhen they are used as the `body` of an `Expression`, 3781*912701f9SAndroid Build Coastguard Workerthey represent _expression_ values with no _annotation_. 3782*912701f9SAndroid Build Coastguard Worker 3783*912701f9SAndroid Build Coastguard Worker`Literal` represents all literal values, both _quoted_ and _unquoted_. 3784*912701f9SAndroid Build Coastguard WorkerThe presence or absence of quotes is not preserved by the data model. 3785*912701f9SAndroid Build Coastguard WorkerThe `value` of `Literal` is the "cooked" value (i.e. escape sequences are processed). 3786*912701f9SAndroid Build Coastguard Worker 3787*912701f9SAndroid Build Coastguard WorkerIn a `VariableRef`, the `name` does not include the initial `$` of the _variable_. 3788*912701f9SAndroid Build Coastguard Worker 3789*912701f9SAndroid Build Coastguard Worker```ts 3790*912701f9SAndroid Build Coastguard Workerinterface Literal { 3791*912701f9SAndroid Build Coastguard Worker type: "literal"; 3792*912701f9SAndroid Build Coastguard Worker value: string; 3793*912701f9SAndroid Build Coastguard Worker} 3794*912701f9SAndroid Build Coastguard Worker 3795*912701f9SAndroid Build Coastguard Workerinterface VariableRef { 3796*912701f9SAndroid Build Coastguard Worker type: "variable"; 3797*912701f9SAndroid Build Coastguard Worker name: string; 3798*912701f9SAndroid Build Coastguard Worker} 3799*912701f9SAndroid Build Coastguard Worker``` 3800*912701f9SAndroid Build Coastguard Worker 3801*912701f9SAndroid Build Coastguard WorkerA `FunctionAnnotation` represents a _function_ _annotation_. 3802*912701f9SAndroid Build Coastguard WorkerThe `name` does not include the `:` starting sigil. 3803*912701f9SAndroid Build Coastguard Worker 3804*912701f9SAndroid Build Coastguard WorkerEach _option_ is represented by an `Option`. 3805*912701f9SAndroid Build Coastguard Worker 3806*912701f9SAndroid Build Coastguard Worker```ts 3807*912701f9SAndroid Build Coastguard Workerinterface FunctionAnnotation { 3808*912701f9SAndroid Build Coastguard Worker type: "function"; 3809*912701f9SAndroid Build Coastguard Worker name: string; 3810*912701f9SAndroid Build Coastguard Worker options: Option[]; 3811*912701f9SAndroid Build Coastguard Worker} 3812*912701f9SAndroid Build Coastguard Worker 3813*912701f9SAndroid Build Coastguard Workerinterface Option { 3814*912701f9SAndroid Build Coastguard Worker name: string; 3815*912701f9SAndroid Build Coastguard Worker value: Literal | VariableRef; 3816*912701f9SAndroid Build Coastguard Worker} 3817*912701f9SAndroid Build Coastguard Worker``` 3818*912701f9SAndroid Build Coastguard Worker 3819*912701f9SAndroid Build Coastguard WorkerAn `UnsupportedAnnotation` represents a 3820*912701f9SAndroid Build Coastguard Worker_private-use annotation_ not supported by the implementation or a _reserved annotation_. 3821*912701f9SAndroid Build Coastguard WorkerThe `source` is the "raw" value (i.e. escape sequences are not processed), 3822*912701f9SAndroid Build Coastguard Workerincluding the starting sigil. 3823*912701f9SAndroid Build Coastguard Worker 3824*912701f9SAndroid Build Coastguard WorkerWhen parsing the syntax of a _message_ that includes a _private-use annotation_ 3825*912701f9SAndroid Build Coastguard Workersupported by the implementation, 3826*912701f9SAndroid Build Coastguard Workerthe implementation SHOULD represent it in the data model 3827*912701f9SAndroid Build Coastguard Workerusing an interface appropriate for the semantics and meaning 3828*912701f9SAndroid Build Coastguard Workerthat the implementation attaches to that _annotation_. 3829*912701f9SAndroid Build Coastguard Worker 3830*912701f9SAndroid Build Coastguard Worker```ts 3831*912701f9SAndroid Build Coastguard Workerinterface UnsupportedAnnotation { 3832*912701f9SAndroid Build Coastguard Worker type: "unsupported-annotation"; 3833*912701f9SAndroid Build Coastguard Worker source: string; 3834*912701f9SAndroid Build Coastguard Worker} 3835*912701f9SAndroid Build Coastguard Worker``` 3836*912701f9SAndroid Build Coastguard Worker 3837*912701f9SAndroid Build Coastguard Worker### Markup 3838*912701f9SAndroid Build Coastguard Worker 3839*912701f9SAndroid Build Coastguard WorkerA `Markup` object has a `kind` of either `"open"`, `"standalone"`, or `"close"`, 3840*912701f9SAndroid Build Coastguard Workereach corresponding to _open_, _standalone_, and _close_ _markup_. 3841*912701f9SAndroid Build Coastguard WorkerThe `name` in these does not include the starting sigils `#` and `/` 3842*912701f9SAndroid Build Coastguard Workeror the ending sigil `/`. 3843*912701f9SAndroid Build Coastguard WorkerThe optional `options` for markup use the same `Option` as `FunctionAnnotation`. 3844*912701f9SAndroid Build Coastguard Worker 3845*912701f9SAndroid Build Coastguard Worker```ts 3846*912701f9SAndroid Build Coastguard Workerinterface Markup { 3847*912701f9SAndroid Build Coastguard Worker type: "markup"; 3848*912701f9SAndroid Build Coastguard Worker kind: "open" | "standalone" | "close"; 3849*912701f9SAndroid Build Coastguard Worker name: string; 3850*912701f9SAndroid Build Coastguard Worker options: Option[]; 3851*912701f9SAndroid Build Coastguard Worker attributes: Attribute[]; 3852*912701f9SAndroid Build Coastguard Worker} 3853*912701f9SAndroid Build Coastguard Worker``` 3854*912701f9SAndroid Build Coastguard Worker 3855*912701f9SAndroid Build Coastguard Worker### Extensions 3856*912701f9SAndroid Build Coastguard Worker 3857*912701f9SAndroid Build Coastguard WorkerImplementations MAY extend this data model with additional interfaces, 3858*912701f9SAndroid Build Coastguard Workeras well as adding new fields to existing interfaces. 3859*912701f9SAndroid Build Coastguard WorkerWhen encountering an unfamiliar field, an implementation MUST ignore it. 3860*912701f9SAndroid Build Coastguard WorkerFor example, an implementation could include a `span` field on all interfaces 3861*912701f9SAndroid Build Coastguard Workerencoding the corresponding start and end positions in its source syntax. 3862*912701f9SAndroid Build Coastguard Worker 3863*912701f9SAndroid Build Coastguard WorkerIn general, 3864*912701f9SAndroid Build Coastguard Workerimplementations MUST NOT extend the sets of values for any defined field or type 3865*912701f9SAndroid Build Coastguard Workerwhen representing a valid message. 3866*912701f9SAndroid Build Coastguard WorkerHowever, when using this data model to represent an invalid message, 3867*912701f9SAndroid Build Coastguard Workeran implementation MAY do so. 3868*912701f9SAndroid Build Coastguard WorkerThis is intended to allow for the representation of "junk" or invalid content within messages. 3869*912701f9SAndroid Build Coastguard Worker 3870*912701f9SAndroid Build Coastguard Worker## Appendices 3871*912701f9SAndroid Build Coastguard Worker 3872*912701f9SAndroid Build Coastguard Worker### Security Considerations 3873*912701f9SAndroid Build Coastguard Worker 3874*912701f9SAndroid Build Coastguard WorkerMessageFormat 2.0 _patterns_ are meant to allow a _message_ to include any string value 3875*912701f9SAndroid Build Coastguard Workerwhich users might normally wish to use in their environment. 3876*912701f9SAndroid Build Coastguard WorkerProgramming languages and other environments vary in what characters are permitted 3877*912701f9SAndroid Build Coastguard Workerto appear in a valid string. 3878*912701f9SAndroid Build Coastguard WorkerIn many cases, certain types of characters, such as invisible control characters, 3879*912701f9SAndroid Build Coastguard Workerrequire escaping by these host formats. 3880*912701f9SAndroid Build Coastguard WorkerIn other cases, strings are not permitted to contain certain characters at all. 3881*912701f9SAndroid Build Coastguard WorkerSince _messages_ are subject to the restrictions and limitations of their 3882*912701f9SAndroid Build Coastguard Workerhost environments, their serializations and resource formats, 3883*912701f9SAndroid Build Coastguard Workerthat might be sufficient to prevent most problems. 3884*912701f9SAndroid Build Coastguard WorkerHowever, MessageFormat itself does not supply such a restriction. 3885*912701f9SAndroid Build Coastguard Worker 3886*912701f9SAndroid Build Coastguard WorkerMessageFormat _messages_ permit nearly all Unicode code points, 3887*912701f9SAndroid Build Coastguard Workerwith the exception of surrogates, 3888*912701f9SAndroid Build Coastguard Workerto appear in _literals_, including the text portions of a _pattern_. 3889*912701f9SAndroid Build Coastguard WorkerThis means that it can be possible for a _message_ to contain invisible characters 3890*912701f9SAndroid Build Coastguard Worker(such as bidirectional controls, 3891*912701f9SAndroid Build Coastguard WorkerASCII control characters in the range U+0000 to U+001F, 3892*912701f9SAndroid Build Coastguard Workeror characters that might be interpreted as escapes or syntax in the host format) 3893*912701f9SAndroid Build Coastguard Workerthat abnormally affect the display of the _message_ 3894*912701f9SAndroid Build Coastguard Workerwhen viewed as source code, or in resource formats or translation tools, 3895*912701f9SAndroid Build Coastguard Workerbut do not generate errors from MessageFormat parsers or processing APIs. 3896*912701f9SAndroid Build Coastguard Worker 3897*912701f9SAndroid Build Coastguard WorkerBidirectional text containing right-to-left characters (such as used for Arabic or Hebrew) 3898*912701f9SAndroid Build Coastguard Workeralso poses a potential source of confusion for users. 3899*912701f9SAndroid Build Coastguard WorkerSince MessageFormat 2.0's syntax makes use of 3900*912701f9SAndroid Build Coastguard Workerkeywords and symbols that are left-to-right or consist of neutral characters 3901*912701f9SAndroid Build Coastguard Worker(including characters subject to mirroring under the Unicode Bidirectional Algorithm), 3902*912701f9SAndroid Build Coastguard Workerit is possible to create messages that, 3903*912701f9SAndroid Build Coastguard Workerwhen displayed in source code, or in resource formats or translation tools, 3904*912701f9SAndroid Build Coastguard Workerhave a misleading appearance or are difficult to parse visually. 3905*912701f9SAndroid Build Coastguard Worker 3906*912701f9SAndroid Build Coastguard WorkerFor more information, see \[[UTS#55](https://unicode.org/reports/tr55/)\] 3907*912701f9SAndroid Build Coastguard Worker<cite>Unicode Source Code Handling</cite>. 3908*912701f9SAndroid Build Coastguard Worker 3909*912701f9SAndroid Build Coastguard WorkerMessageFormat 2.0 implementations might allow end-users to install 3910*912701f9SAndroid Build Coastguard Worker_selectors_, _functions_, or _markup_ from third-party sources. 3911*912701f9SAndroid Build Coastguard WorkerSuch functionality can be a vector for various exploits, 3912*912701f9SAndroid Build Coastguard Workerincluding buffer overflow, code injection, user tracking, 3913*912701f9SAndroid Build Coastguard Workerfingerprinting, and other types of bad behavior. 3914*912701f9SAndroid Build Coastguard WorkerAny installed code needs to be appropriately sandboxed. 3915*912701f9SAndroid Build Coastguard WorkerIn addition, end-users need to be aware of the risks involved. 3916*912701f9SAndroid Build Coastguard Worker 3917*912701f9SAndroid Build Coastguard Worker### Acknowledgements 3918*912701f9SAndroid Build Coastguard Worker 3919*912701f9SAndroid Build Coastguard WorkerSpecial thanks to the following people for their contributions to making MessageFormat v2. 3920*912701f9SAndroid Build Coastguard WorkerThe following people contributed to our github repo and are listed in order by contribution size: 3921*912701f9SAndroid Build Coastguard Worker 3922*912701f9SAndroid Build Coastguard WorkerAddison Phillips, 3923*912701f9SAndroid Build Coastguard WorkerEemeli Aro, 3924*912701f9SAndroid Build Coastguard WorkerRomulo Cintra, 3925*912701f9SAndroid Build Coastguard WorkerStanisław Małolepszy, 3926*912701f9SAndroid Build Coastguard WorkerElango Cheran, 3927*912701f9SAndroid Build Coastguard WorkerRichard Gibson, 3928*912701f9SAndroid Build Coastguard WorkerTim Chevalier, 3929*912701f9SAndroid Build Coastguard WorkerMihai Niță, 3930*912701f9SAndroid Build Coastguard WorkerShane F. Carr, 3931*912701f9SAndroid Build Coastguard WorkerMark Davis, 3932*912701f9SAndroid Build Coastguard WorkerSteven R. Loomis, 3933*912701f9SAndroid Build Coastguard WorkerCaleb Maclennan, 3934*912701f9SAndroid Build Coastguard WorkerDavid Filip, 3935*912701f9SAndroid Build Coastguard WorkerDaniel Minor, 3936*912701f9SAndroid Build Coastguard WorkerChristopher Dieringer, 3937*912701f9SAndroid Build Coastguard WorkerGeorge Rhoten, 3938*912701f9SAndroid Build Coastguard WorkerUjjwal Sharma, 3939*912701f9SAndroid Build Coastguard WorkerDaniel Ehrenberg, 3940*912701f9SAndroid Build Coastguard WorkerMarkus Scherer, 3941*912701f9SAndroid Build Coastguard WorkerZibi Braniecki, 3942*912701f9SAndroid Build Coastguard WorkerMatt Radbourne, 3943*912701f9SAndroid Build Coastguard WorkerBruno Haible, 3944*912701f9SAndroid Build Coastguard Workerand Rafael Xavier de Souza. 3945*912701f9SAndroid Build Coastguard Worker 3946*912701f9SAndroid Build Coastguard WorkerAddison Phillips was chair of the working group from January 2023. 3947*912701f9SAndroid Build Coastguard WorkerPrior to 2023, the group was governed by a chair group, consisting of 3948*912701f9SAndroid Build Coastguard WorkerRomulo Cintra, 3949*912701f9SAndroid Build Coastguard WorkerElango Cheran, 3950*912701f9SAndroid Build Coastguard WorkerMihai Niță, 3951*912701f9SAndroid Build Coastguard WorkerDavid Filip, 3952*912701f9SAndroid Build Coastguard WorkerNicolas Bouvrette, 3953*912701f9SAndroid Build Coastguard WorkerStanisław Małolepszy, 3954*912701f9SAndroid Build Coastguard WorkerRafael Xavier de Souza, 3955*912701f9SAndroid Build Coastguard WorkerAddison Phillips, 3956*912701f9SAndroid Build Coastguard Workerand Daniel Minor. 3957*912701f9SAndroid Build Coastguard WorkerRomulo Cintra chaired the chair group. 3958*912701f9SAndroid Build Coastguard Worker 3959*912701f9SAndroid Build Coastguard Worker* * * 3960*912701f9SAndroid Build Coastguard Worker 3961*912701f9SAndroid Build Coastguard WorkerCopyright © 2001–2024 Unicode, Inc. All Rights Reserved. The Unicode Consortium makes no expressed or implied warranty of any kind, and assumes no liability for errors or omissions. No liability is assumed for incidental and consequential damages in connection with or arising out of the use of the information or programs contained or accompanying this technical report. The Unicode [Terms of Use](https://www.unicode.org/copyright.html) apply. 3962*912701f9SAndroid Build Coastguard Worker 3963*912701f9SAndroid Build Coastguard WorkerUnicode and the Unicode logo are trademarks of Unicode, Inc., and are registered in some jurisdictions. 3964