Thanks to visit codestin.com
Credit goes to github.com

Skip to content

data-model: Better represent annotations in the data model, particularly when unsupported #554

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

Merged
merged 7 commits into from
Dec 8, 2023
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
37 changes: 17 additions & 20 deletions spec/data-model/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,28 +117,33 @@ The `body` strings are the "cooked" _text_ values, i.e. escape sequences are pro

Implementations MUST NOT rely on the set of `Expression` interfaces being exhaustive,
as future versions of this specification MAY define additional expressions.
An `Expression` `func` with an unrecognized value SHOULD be treated as an `UnsupportedExpression` value.

```ts
interface Pattern {
body: Array<string | Expression>;
}

type Expression = LiteralExpression | VariableExpression | FunctionExpression;
type Expression = LiteralExpression | VariableExpression | FunctionExpression |
UnsupportedExpression;

interface LiteralExpression {
arg: Literal;
func?: FunctionRef | UnsupportedExpression;
annotation?: FunctionAnnotation | UnsupportedAnnotation;
}

interface VariableExpression {
arg: VariableRef;
func?: FunctionRef | UnsupportedExpression;
annotation?: FunctionAnnotation | UnsupportedAnnotation;
}

interface FunctionExpression {
arg?: never;
func: FunctionRef | UnsupportedExpression;
annotation: FunctionAnnotation;
}

interface UnsupportedExpression {
arg?: never;
annotation: UnsupportedAnnotation;
}
```

Expand Down Expand Up @@ -166,22 +171,19 @@ interface VariableRef {
}
```

A `FunctionRef` represents an _expression_ with a _function_ _annotation_.
In a `FunctionRef`,
A `FunctionAnnotation` represents a _function_ _annotation_.
In a `FunctionAnnotation`,
the `kind` corresponds to the starting sigil of a _function_:
`'open'` for `+`, `'close'` for `-`, and `'value'` for `:`.
The `name` does not include this starting sigil.

The optional `operand` is the _literal_ or _variable_
before the _annotation_ in the _expression_, if present.
Each _option_ is represented by an `Option`.

```ts
interface FunctionRef {
interface FunctionAnnotation {
type: "function";
kind: "open" | "close" | "value";
name: string;
operand?: Literal | VariableRef;
options?: Option[];
}

Expand All @@ -191,9 +193,8 @@ interface Option {
}
```

An `UnsupportedExpression` represents an _expression_ with a
_reserved annotation_ or a _private-use annotation_ not supported
by the implementation.
An `UnsupportedAnnotation` represents a
_private-use annotation_ not supported by the implementation or a _reserved annotation_.
The `sigil` corresponds to the starting sigil of the _annotation_.
The `source` is the "raw" value (i.e. escape sequences are not processed)
and does not include the starting `sigil`.
Expand All @@ -204,21 +205,17 @@ and does not include the starting `sigil`.
> This would result in new interfaces being added to
> this data model.

If the _expression_ includes a _literal_ or _variable_ before the _annotation_,
it is included as the `operand`.

When parsing the syntax of a _message_ that includes a _private-use annotation_
supported by the implementation,
the implementation SHOULD represent it in the data model
using an interface appropriate for the semantics and meaning
that the implementation attaches to that _annotation_.

```ts
interface UnsupportedExpression {
type: "unsupported-expression";
interface UnsupportedAnnotation {
type: "unsupported-annotation";
sigil: "!" | "@" | "#" | "%" | "^" | "&" | "*" | "<" | ">" | "/" | "?" | "~";
source: string;
operand?: Literal | VariableRef;
}
```

Expand Down
12 changes: 6 additions & 6 deletions spec/data-model/message.dtd
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
<!ELEMENT pattern (#PCDATA | expression)*>

<!ELEMENT expression (
((literal | variable), (function | unsupportedExpression)?) |
function | unsupportedExpression
((literal | variable), (functionAnnotation | unsupportedAnnotation)?) |
functionAnnotation | unsupportedAnnotation
)>

<!ELEMENT literal (#PCDATA)>
Expand All @@ -34,13 +34,13 @@
<!ELEMENT variable (EMPTY)>
<!ATTLIST variable name NMTOKEN #REQUIRED>

<!ELEMENT function (option)*>
<!ATTLIST function
<!ELEMENT functionAnnotation (option)*>
<!ATTLIST functionAnnotation
kind (open | close | value) #REQUIRED
name NMTOKEN #REQUIRED
>
<!ELEMENT option (literal | variable)>
<!ATTLIST option name NMTOKEN #REQUIRED>

<!ELEMENT unsupportedExpression (#PCDATA)>
<!ATTLIST unsupportedExpression sigil CDATA #REQUIRED>
<!ELEMENT unsupportedAnnotation (#PCDATA)>
<!ATTLIST unsupportedAnnotation sigil CDATA #REQUIRED>
50 changes: 29 additions & 21 deletions spec/data-model/message.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,76 +22,84 @@
},
"required": ["type", "name"]
},
"value": {
"oneOf": [{ "$ref": "#/$defs/literal" }, { "$ref": "#/$defs/variable" }]
"option": {
"type": "object",
"properties": {
"name": { "type": "string" },
"value": {
"oneOf": [{ "$ref": "#/$defs/literal" }, { "$ref": "#/$defs/variable" }]
}
},
"required": ["name", "value"]
},

"function": {
"function-annotation": {
"type": "object",
"properties": {
"type": { "const": "function" },
"kind": { "enum": ["open", "close", "value"] },
"name": { "type": "string" },
"options": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"value": { "$ref": "#/$defs/value" }
},
"required": ["name", "value"]
}
"items": { "$ref": "#/$defs/option" }
}
},
"required": ["type", "kind", "name"]
},
"unsupported-expression": {
"unsupported-annotation": {
"type": "object",
"properties": {
"type": { "const": "unsupported-expression" },
"type": { "const": "unsupported-annotation" },
"sigil": {
"enum": ["!", "@", "#", "%", "^", "&", "*", "<", ">", "?", "~"]
"enum": ["!", "@", "#", "%", "^", "&", "*", "<", ">", "/", "?", "~"]
},
"source": { "type": "string" }
},
"required": ["type", "sigil", "source"]
},
"annotation": {
"oneOf": [
{ "$ref": "#/$defs/function" },
{ "$ref": "#/$defs/unsupported-expression" }
{ "$ref": "#/$defs/function-annotation" },
{ "$ref": "#/$defs/unsupported-annotation" }
]
},

"literal-expression": {
"type": "object",
"properties": {
"arg": { "$ref": "#/$defs/literal" },
"func": { "$ref": "#/$defs/annotation" }
"annotation": { "$ref": "#/$defs/annotation" }
},
"required": ["arg"]
},
"variable-expression": {
"type": "object",
"properties": {
"arg": { "$ref": "#/$defs/variable" },
"func": { "$ref": "#/$defs/annotation" }
"annotation": { "$ref": "#/$defs/annotation" }
},
"required": ["arg"]
},
"function-expression": {
"type": "object",
"properties": {
"func": { "$ref": "#/$defs/annotation" }
"annotation": { "$ref": "#/$defs/function-annotation" }
},
"required": ["func"]
"required": ["annotation"]
},
"unsupported-expression": {
"type": "object",
"properties": {
"annotation": { "$ref": "#/$defs/unsupported-annotation" }
},
"required": ["annotation"]
},
"expression": {
"oneOf": [
{ "$ref": "#/$defs/literal-expression" },
{ "$ref": "#/$defs/variable-expression" },
{ "$ref": "#/$defs/function-expression" }
{ "$ref": "#/$defs/function-expression" },
{ "$ref": "#/$defs/unsupported-expression" }
]
},

Expand Down
6 changes: 3 additions & 3 deletions spec/message.abnf
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ selector = expression
variant = key *(s key) [s] quoted-pattern
key = literal / "*"

expression = literal-expression / variable-expression / function-expression
expression = literal-expression / variable-expression / annotation-expression
literal-expression = "{" [s] literal [s annotation] [s] "}"
variable-expression = "{" [s] variable [s annotation] [s] "}"
function-expression = "{" [s] annotation [s] "}"
annotation-expression = "{" [s] annotation [s] "}"
annotation = (function *(s option))
/ reserved-annotation
/ private-use-annotation
/ reserved-annotation

literal = quoted / unquoted
variable = "$" name
Expand Down
10 changes: 5 additions & 5 deletions spec/syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -431,13 +431,13 @@ optionally followed by an _annotation_.
A **_<dfn>variable-expression</dfn>_** contains a _variable_,
optionally followed by an _annotation_.

A **_<dfn>function-expression</dfn>_** contains only an _annotation_.
An **_<dfn>annotation-expression</dfn>_** contains an _annotation_ without an _operand_.

```abnf
expression = literal-expression / variable-expression / function-expression
expression = literal-expression / variable-expression / annotation-expression
literal-expression = "{" [s] literal [s annotation] [s] "}"
variable-expression = "{" [s] variable [s annotation] [s] "}"
function-expression = "{" [s] annotation [s] "}"
annotation-expression = "{" [s] annotation [s] "}"
```

There are several types of _expression_ that can appear in a _message_.
Expand Down Expand Up @@ -476,12 +476,12 @@ Additionally, an _input-declaration_ can contain a _variable-expression_.

An **_<dfn>annotation</dfn>_** is part of an _expression_ containing either
a _function_ together with its associated _options_, or
a _reserved annotation_ or a _private-use annotation_.
a _private-use annotation_ or a _reserved annotation_.

```abnf
annotation = (function *(s option))
/ reserved-annotation
/ private-use-annotation
/ reserved-annotation
```

An **_<dfn>operand</dfn>_** is the _literal_ of a _literal-expression_ or
Expand Down