Skip to content

Commit

Permalink
Added Structured Annotations (#265)
Browse files Browse the repository at this point in the history
* Added Structured Annotations per #264

* Modified protobuf schema per review discussion, added nested expressions example and made additional clarifications.

* Simplify expressions within StructureAnnotations to base types (no nesting).

* Added missing empty ExpressionList to example.

* remove backtics

Co-Authored-By: Antonin Bas <[email protected]>

* Make subsection for Structured Anno examples

Co-Authored-By: Antonin Bas <[email protected]>

* Remove duplicate line.

* Added statement about empty expressionLists. Fixed bilio entry.

* Added "structured" to statement about empty expressionLists.

* Changed "could" to "may." Spell P4Info consistently.

* Removed empty exressionList from @empty structured annotation example to agree with latest P4-16 spec in progress.

Co-authored-by: Chris Sommers <[email protected]>
Co-authored-by: Antonin Bas <[email protected]>
  • Loading branch information
3 people authored Mar 27, 2020
1 parent 5a30975 commit c9cd4af
Show file tree
Hide file tree
Showing 4 changed files with 214 additions and 0 deletions.
169 changes: 169 additions & 0 deletions docs/v1/P4Runtime-Spec.mdk
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,7 @@ message Preamble {
repeated string annotations = 4;
// Documentation of the entity
Documentation doc = 5;
repeated StructuredAnnotation structured_annotations = 6;
}
~ End Proto

Expand Down Expand Up @@ -1020,6 +1021,172 @@ table my_ipv4_lkup {
}
~ End p4example

### Structured Annotations

P4 supports both unstructured and structured annotations [@P4Annotations].
Unstructured annotations of the form `MyAnno1` or `MyAnno2(body-content)` can
either be empty, or contain free-form content; anything between the pair of
matched parentheses is legal. Conversely, structured annotations of the form
`MyAnno3[]` or `MyAnno4[kvList|expressionList]` have a more prescribed syntax,
which allows declaring key-value lists or expression lists. Both unstructured
and structured annotations may be used simultaneously on a P4 element and
P4Info supports this.

The annotations described up to this point, &eg; `@brief()`, have all been
unstructured annotations, or simply annotations. These are represented in
P4Info as `repeated string annotations` fields in the various `message`s.
Similarly, structured annotations are represented in `repeated
StructuredAnnotation structured_annotations` fields which are siblings to the
unstructured `annotations`. The `structured_annotations` contain parsed
representations of the original annotation source. This parsing includes
expression-evaluation, so the resulting P4Info may contain a simplified
replica of the original structured annotations.

The structured annotation messages are defined in p4types.proto.

~ Begin Proto
message KeyValuePair {
string key = 1;
Expression value = 2;
}

message KeyValuePairList {
repeated KeyValuePair kv_pairs = 1;
}

message Expression {
oneof value {
string string_value = 1;
int64 int64_value = 2;
bool bool_value = 3;
}
}

message ExpressionList {
repeated Expression expressions = 1;
}

message StructuredAnnotation {
string name = 1;
oneof body {
ExpressionList expression_list = 2;
KeyValuePairList kvpair_list = 3;
}
}
~ End Proto

The `StructuredAnnotation` message can represent either a `KeyValuePairList`
or an `ExpressionList`.

The type of an expression is intentionally limited to one of the following
base types: string literal, 64-bit signed integer, or boolean. The `p4c`
compiler frontend which generates P4Info will evaluate all expressions and
simplify them to one of the valid types. Any expressions which don't match one
of the valid types will generate an error. For integers exceeding 64 bits,
besides issuing an error, the compiler *may* print a suggestion to use a
string representation, and the P4Info consumer may perform any necessary
conversions.

The following invariants hold:

1. For any P4 entity, there are no two `StructuredAnnotation`s that have the
same name.

2. Within a `KeyValuePairList`, there are no two `KeyValuePair`s that have the
same `key.`

#### Structured Annotation Examples

**Empty Expression List**

~ Begin P4Example
@Empty[]
table t {
...
}
~ End P4Example

The generated P4Info will contain the following.

~ Begin Proto
structured_annotations {
name: "Empty"
}
~ End Proto

**Mixed Expression List**

~ Begin P4Example
#define TEXT_CONST "hello"
#define NUM_CONST 6
@MixedExprList[1,TEXT_CONST,true,1==2,5+NUM_CONST]
table t {
...
}
~ End P4Example

The generated P4Info will contain:

~ Begin Proto
structured_annotations {
name: "MixedExprList"
expression_list {
expressions {
int64_value: 1
}
expressions {
string_value: "hello"
}
expressions {
bool_value: true
}
expressions {
bool_value: false
}
expressions {
int64_value: 11
}
}
}
~ End Proto

**kvList of Mixed Expressions**

~ Begin P4Example
@MixedKV[label="text", my_bool=true, int_val=2*3]
table t {
...
}
~ End P4Example

The generated P4Info will contain:

~ Begin Proto
structured_annotations {
name: "MixedKV"
kvpair_list {
kv_pairs {
key: "label"
value {
string_value: "text"
}
}
kv_pairs {
key: "my_bool"
value {
bool_value: true
}
}
kv_pairs {
key: "int_val"
value {
int64_value: 6
}
}
}
}
~ End Proto

## `PkgInfo` Message

The `PkgInfo` message contains package-level metadata which describes the
Expand Down Expand Up @@ -1048,6 +1215,8 @@ message PkgInfo {
string contact = 7;
// url for more information, e.g. "http://support.p4.org/ref/p4/switch.p4_v1.0"
string url = 8;
// Miscellaneous metadata, structured; a way to extend PkgInfo
repeated StructuredAnnotation structured_annotations = 9;
}
~ End Proto

Expand Down
5 changes: 5 additions & 0 deletions docs/v1/references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,11 @@ @ONLINE { ProtoOneOfBackwardsCompatibility
url = "https://developers.google.com/protocol-buffers/docs/proto3#backwards-compatibility-issues"
}

@ONLINE { P4Annotations,
title = "P4 Annotations",
url = "https://p4.org/p4-spec/docs/P4-16-working-spec.html#sec-annotations"
}

@ONLINE { v1model,
title = "v1model Architecture Definition",
url = "https://github.com/p4lang/p4c/blob/master/p4include/v1model.p4"
Expand Down
6 changes: 6 additions & 0 deletions proto/p4/config/v1/p4info.proto
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ message PkgInfo {
string contact = 7;
// url for more information, e.g. "http://support.p4.org/ref/p4/switch.p4_v1.0"
string url = 8;
// Miscellaneous metadata, structured; a way to extend PkgInfo
repeated StructuredAnnotation structured_annotations = 9;
}

// wrapping the enum in a message to avoid name collisions in C++, where "enum
Expand Down Expand Up @@ -130,6 +132,7 @@ message Preamble {
repeated string annotations = 4;
// Documentation of the entity
Documentation doc = 5;
repeated StructuredAnnotation structured_annotations = 6;
}

// used to group all extern instances of the same type in one message
Expand Down Expand Up @@ -171,6 +174,7 @@ message MatchField {
Documentation doc = 6;
// unset if not user-defined type
P4NamedType type_name = 8;
repeated StructuredAnnotation structured_annotations = 9;
}

message Table {
Expand Down Expand Up @@ -231,6 +235,7 @@ message Action {
Documentation doc = 5;
// unset if not user-defined type
P4NamedType type_name = 6;
repeated StructuredAnnotation structured_annotations = 7;
}
repeated Param params = 2;
}
Expand Down Expand Up @@ -322,6 +327,7 @@ message ControllerPacketMetadata {
int32 bitwidth = 4;
// unset if not user-defined type
P4NamedType type_name = 5;
repeated StructuredAnnotation structured_annotations = 6;
}
// Ordered based on header layout.
// This is a constraint on the generator of this P4Info.
Expand Down
34 changes: 34 additions & 0 deletions proto/p4/config/v1/p4types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -154,15 +154,46 @@ message P4HeaderUnionStackTypeSpec {
int32 size = 2;
}

message KeyValuePair {
string key = 1;
Expression value = 2;
}

message KeyValuePairList {
repeated KeyValuePair kv_pairs = 1;
}

message Expression {
oneof value {
string string_value = 1;
int64 int64_value = 2;
bool bool_value = 3;
}
}

message ExpressionList {
repeated Expression expressions = 1;
}

message StructuredAnnotation {
string name = 1;
oneof body {
ExpressionList expression_list = 2;
KeyValuePairList kvpair_list = 3;
}
}

// For "safe" enums with no underlying representation and no member integer
// values.
message P4EnumTypeSpec {
message Member {
string name = 1;
repeated string annotations = 2;
repeated StructuredAnnotation structured_annotations = 3;
}
repeated Member members = 1;
repeated string annotations = 2;
repeated StructuredAnnotation structured_annotations = 3;
}

// For serializable (or "unsafe") enums, which have an underlying type. Note
Expand All @@ -173,10 +204,12 @@ message P4SerializableEnumTypeSpec {
string name = 1;
bytes value = 2;
repeated string annotations = 3;
repeated StructuredAnnotation structured_annotations = 4;
}
P4BitTypeSpec underlying_type = 1;
repeated Member members = 2;
repeated string annotations = 3;
repeated StructuredAnnotation structured_annotations = 4;
}

// Similar to an enum, but there is always one and only one instance per P4
Expand Down Expand Up @@ -204,6 +237,7 @@ message P4NewTypeSpec {
}
// for other annotations (not @p4runtime_translation)
repeated string annotations = 3;
repeated StructuredAnnotation structured_annotations = 4;
}

// End of P4 type specs --------------------------------------------------------

0 comments on commit c9cd4af

Please sign in to comment.