Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify error & fallback handling #879

Merged
merged 6 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions spec/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Some examples include throwing an exception,
returning an error code,
or providing a function or method for enumerating any errors.

For all _messages_ without _Syntax Errors_ or _Data Model Errors_,
For all _valid_ _messages_,
an implementation MUST enable a user to get a formatted result.
The formatted result might include _fallback values_
such as when a _placeholder_'s _expression_ produced an error
Expand All @@ -52,7 +52,7 @@ and a _Resolution Error_ or a _Message Function Error_ MUST be emitted.

## Syntax Errors

**_<dfn>Syntax Errors</dfn>_** occur when the syntax representation of a message is not well-formed.
**_<dfn>Syntax Errors</dfn>_** occur when the syntax representation of a message is not _well-formed_.

> Example invalid messages resulting in a _Syntax Error_:
>
Expand All @@ -74,7 +74,7 @@ and a _Resolution Error_ or a _Message Function Error_ MUST be emitted.

## Data Model Errors

**_<dfn>Data Model Errors</dfn>_** occur when a message is invalid due to
**_<dfn>Data Model Errors</dfn>_** occur when a message is not _valid_ due to
violating one of the semantic requirements on its structure.

### Variant Key Mismatch
Expand Down
77 changes: 40 additions & 37 deletions spec/formatting.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,19 @@ when formatting a message for display in a user interface, or for some later pro

To start, we presume that a _message_ has either been parsed from its syntax
or created from a data model description.
If this construction has encountered any _Syntax Errors_ or _Data Model Errors_,
an appropriate error MUST be emitted and a _fallback value_ MAY be used as the formatting result.
If the resulting _message_ is not _well-formed_, a _Syntax Error_ is emitted.
If the resulting _message_ is _well-formed_ but is not _valid_, a _Data Model Error_ is emitted.

Formatting of a _message_ is defined by the following operations:
The formatting of a _message_ is defined by the following operations:

- **_<dfn>Pattern Selection</dfn>_** determines which of a message's _patterns_ is formatted.
For a message with no _selectors_, this is simple as there is only one _pattern_.
With _selectors_, this will depend on their resolution.

- **_<dfn>Formatting</dfn>_** takes the resolved values of the selected _pattern_,
eemeli marked this conversation as resolved.
Show resolved Hide resolved
and produces the formatted result for the _message_.
Depending on the implementation, this result could be a single concatenated string,
an array of objects, an attributed string, or some other locally appropriate data type.

- **_<dfn>Expression and Markup Resolution</dfn>_** determines the value of an _expression_ or _markup_,
with reference to the current _formatting context_.
Expand All @@ -24,6 +33,15 @@ Formatting of a _message_ is defined by the following operations:
The resolution of _text_ is rather straightforward,
and is detailed under _literal resolution_.

Implementations are not required to expose
the _expression resolution_ and _pattern selection_ operations to their users,
or even use them in their internal processing,
as long as the final _formatting_ result is made available to users
and the observable behavior of the _formatting_ matches that described here.

_Attributes_ MUST NOT have any effect on the formatted output of a _message_,
nor be made available to function implementations.

> [!IMPORTANT]
>
> **This specification does not require either eager or lazy _expression resolution_ of _message_
Expand All @@ -39,27 +57,6 @@ Formatting of a _message_ is defined by the following operations:
> have already been evaluated in the order in which the relevant _declarations_
> and _selectors_ appear in the _message_.

- **_<dfn>Pattern Selection</dfn>_** determines which of a message's _patterns_ is formatted.
For a message with no _selectors_, this is simple as there is only one _pattern_.
With _selectors_, this will depend on their resolution.

At the start of _pattern selection_,
if the _message_ contains any _reserved statements_,
emit an _Unsupported Statement_ error.

- **_<dfn>Formatting</dfn>_** takes the resolved values of the selected _pattern_,
and produces the formatted result for the _message_.
Depending on the implementation, this result could be a single concatenated string,
an array of objects, an attributed string, or some other locally appropriate data type.

Formatter implementations are not required to expose
the _expression resolution_ and _pattern selection_ operations to their users,
or even use them in their internal processing,
as long as the final _formatting_ result is made available to users
and the observable behavior of the formatter matches that described here.

_Attributes_ MUST NOT affect the processing or output of a _message_.

## Formatting Context

A message's **_<dfn>formatting context</dfn>_** represents the data and procedures that are required
Expand All @@ -82,8 +79,7 @@ At a minimum, it includes:
- The _function registry_,
providing the implementations of the functions referred to by message _functions_.

- Optionally, a fallback string to use for the message
if it contains any _Syntax Errors_ or _Data Model Errors_.
- Optionally, a fallback string to use for the message if it is not _valid_.

Implementations MAY include additional fields in their _formatting context_.

Expand Down Expand Up @@ -192,8 +188,8 @@ If a _declaration_ exists for the _variable_, its resolved value is used.
Otherwise, the _variable_ is an implicit reference to an input value,
and its value is looked up from the _formatting context_ _input mapping_.

The resolution of a _variable_ MAY fail if no value is identified for its _name_.
If this happens, an _Unresolved Variable_ error MUST be emitted.
The resolution of a _variable_ fails if no value is identified for its _name_.
If this happens, an _Unresolved Variable_ error is emitted.
If a _variable_ would resolve to a _fallback value_,
this MUST also be considered a failure.

Expand Down Expand Up @@ -435,6 +431,17 @@ _Pattern selection_ is not supported for _fallback values_.

## Pattern Selection

If the _message_ contains any _reserved statements_,
emit an _Unsupported Statement_ error.

If the _message_ being formatted is not _well-formed_ and _valid_,
the result of pattern selection is a _pattern_ consisting of a single _fallback value_
using the _message_'s fallback string defined in the _formatting context_
or if this is not available or empty, the U+FFFD REPLACEMENT CHARACTER `�`.

If the _message_ being formatted does not contain a _matcher_,
the result of pattern selection is its _pattern_ value.
aphillips marked this conversation as resolved.
Show resolved Hide resolved

When a _message_ contains a _matcher_ with one or more _selectors_,
the implementation needs to determine which _variant_ will be used
to provide the _pattern_ for the formatting operation.
Expand Down Expand Up @@ -504,11 +511,6 @@ This selection method is defined in more detail below.
An implementation MAY use any pattern selection method,
as long as its observable behavior matches the results of the method defined here.

If the message being formatted has any _Syntax Errors_ or _Data Model Errors_,
the result of pattern selection MUST be a pattern resolving to a single _fallback value_
using the message's fallback string defined in the _formatting context_
or if this is not available or empty, the U+FFFD REPLACEMENT CHARACTER `�`.

### Resolve Selectors

First, resolve the values of each _selector_:
Expand Down Expand Up @@ -741,8 +743,8 @@ each _text_ and _placeholder_ part of the selected _pattern_ is resolved and for

Resolved values cannot always be formatted by a given implementation.
When such an error occurs during _formatting_,
an implementation MUST emit an appropriate _Message Function Error_ and use a
_fallback value_ for the _placeholder_ with the error.
an appropriate _Message Function Error_ is emitted and
a _fallback value_ is used for the _placeholder_ with the error.

Implementations MAY represent the result of _formatting_ using the most
appropriate data type or structure. Some examples of these include:
Expand Down Expand Up @@ -787,8 +789,9 @@ the _fallback value_ as a string,
and a U+007D RIGHT CURLY BRACKET `}`.

> For example,
> a message with a _Syntax Error_ and no fallback string
> defined in the _formatting context_ would format to a string as `{�}`.
> a _message_ that is not _well-formed_ would format to a string as `{�}`,
> unless a fallback string is defined in the _formatting context_,
> in which case that string would be used instead.

### Handling Bidirectional Text

Expand Down
27 changes: 16 additions & 11 deletions spec/syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ Attempting to parse a _message_ that is not _well-formed_ will result in a _Synt
A _message_ is **_<dfn>valid</dfn>_** if it is _well-formed_ and
**also** meets the additional content restrictions
and semantic requirements about its structure defined below for
_declarations_, _matcher_, _options_, and _attributes_.
_declarations_, _matcher_, and _options_.
Attempting to parse a _message_ that is not _valid_ will result in a _Data Model Error_.

## The Message
Expand Down Expand Up @@ -368,14 +368,18 @@ and at least one _variant_.
When the _matcher_ is processed, the result will be a single _pattern_ that serves
as the template for the formatting process.

A _message_ can only be considered _valid_ if the following requirements are
satisfied:
A _message_ can only be considered _valid_ if the following requirements are satisfied;
otherwise, a corresponding _Data Model Error_ will be produced during processing:

- The number of _keys_ on each _variant_ MUST be equal to the number of _selectors_.
- At least one _variant_ MUST exist whose _keys_ are all equal to the "catch-all" key `*`.
- Each _selector_ MUST have an _annotation_,
- _Variant Key Mismatch_:
The number of _keys_ on each _variant_ MUST be equal to the number of _selectors_.
- _Missing Fallback Variant_:
At least one _variant_ MUST exist whose _keys_ are all equal to the "catch-all" key `*`.
- _Missing Selector Annotation_:
Each _selector_ MUST have an _annotation_,
or contain a _variable_ that directly or indirectly references a _declaration_ with an _annotation_.
Comment on lines +378 to 380
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This text might change on Monday 😸

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm aware; will resolve conflicts after whichever lands first.

- Each _variant_ MUST use a list of _keys_ that is unique from that
- _Duplicate Variant_:
Each _variant_ MUST use a list of _keys_ that is unique from that
of all other _variants_ in the _message_.
_Literal_ _keys_ are compared by their contents, not their syntactical appearance.

Expand Down Expand Up @@ -587,7 +591,8 @@ Multiple _options_ are permitted in an _annotation_.
_Options_ are separated from the preceding _function_ _identifier_
and from each other by whitespace.
Each _option_'s _identifier_ MUST be unique within the _annotation_:
an _annotation_ with duplicate _option_ _identifiers_ is not _valid_.
an _annotation_ with duplicate _option_ _identifiers_ is not _valid_
and will produce a _Duplicate Option Name_ error during processing.

The order of _options_ is not significant.

Expand Down Expand Up @@ -750,10 +755,10 @@ by an U+003D EQUALS SIGN `=` along with optional whitespace.

Multiple _attributes_ are permitted in an _expression_ or _markup_.
Each _attribute_ is separated by whitespace.
Each _attribute_'s _identifier_ MUST be unique within the _expression_ or _markup_:
an _expression_ or _markup_ with duplicate _attribute_ _identifiers_ is not _valid_.

The order of _attributes_ is not significant.
Each _attribute_'s _identifier_ SHOULD be unique within the _expression_ or _markup_:
all but the last _attribute_ with the same _identifier_ are ignored.
The order of _attributes_ is not otherwise significant.

```abnf
attribute = "@" identifier [[s] "=" [s] literal]
Expand Down