blob: e86fb16c952b546b19483887e23dd00f958ef18a [file] [log] [blame] [view]
<!-- WARNING: This file is machine generated by //src/tests/fidl/source_compatibility/gen, do not edit. -->
Note: This document covers API impact only. For more details, see the
[ABI compatibility page](/docs/development/languages/fidl/guides/compatibility/README.md)
# Change a union from flexible to strict
## Overview
-|[init](#init)|[step 1](#step-1)|[step 2](#step-2)|[step 3](#step-3)
---|---|---|---|---
fidl|[link](#fidl-init)||[link](#fidl-2)|
dart|[link](#dart-init)|[link](#dart-1)||[link](#dart-3)
go|[link](#go-init)|[link](#go-1)||
hlcpp|[link](#hlcpp-init)|[link](#hlcpp-1)||[link](#hlcpp-3)
llcpp|[link](#llcpp-init)|[link](#llcpp-1)||[link](#llcpp-3)
rust|[link](#rust-init)|[link](#rust-1)||[link](#rust-3)
## Initial State {#init}
### FIDL {#fidl-init}
```fidl
type JsonValue = flexible union {
1: int_value int32;
2: string_value string:MAX;
};
```
### Dart {#dart-init}
```dart
void useUnion(fidllib.JsonValue value) {
switch (value.$tag) {
case fidllib.JsonValueTag.intValue:
print('int value: ${value.intValue}');
break;
case fidllib.JsonValueTag.stringValue:
print('string value: ${value.stringValue}');
break;
case fidllib.JsonValueTag.$unknown:
print('unknown variant: ${value.$unknownData}');
break;
}
}
```
### Go {#go-init}
```go
func useUnion(value lib.JsonValue) {
switch value.Which() {
case lib.JsonValueIntValue:
fmt.Printf("int value: %d\n", value.IntValue)
case lib.JsonValueStringValue:
fmt.Printf("string value: %s\n", value.StringValue)
case lib.JsonValue_unknownData:
fmt.Printf("unknown data: %+v\n", value.GetUnknownData())
default:
fmt.Println("<unknown tag>")
}
}
```
### HLCPP {#hlcpp-init}
```cpp
void use_union(fidl_test::JsonValue value) {
switch (value.Which()) {
case fidl_test::JsonValue::Tag::kIntValue:
printf("int value: %d\n", value.int_value());
break;
case fidl_test::JsonValue::Tag::kStringValue:
printf("string value: %s\n", value.string_value().c_str());
break;
case fidl_test::JsonValue::Tag::Invalid:
printf("<uninitialized union>\n");
break;
case fidl_test::JsonValue::Tag::kUnknown:
printf("<%lu unknown bytes>\n", value.UnknownBytes()->size());
break;
}
}
```
### LLCPP {#llcpp-init}
```cpp
void use_union(fidl_test::wire::JsonValue* value) {
switch (value->which()) {
case fidl_test::wire::JsonValue::Tag::kIntValue:
printf("int value: %d\n", value->int_value());
break;
case fidl_test::wire::JsonValue::Tag::kStringValue:
printf("string value: %s\n", value->string_value().data());
break;
case fidl_test::wire::JsonValue::Tag::kUnknown:
printf("<unknown data>\n");
break;
}
}
```
### Rust {#rust-init}
```rust
fn use_union(value: &fidl_lib::JsonValue) {
match value {
fidl_lib::JsonValue::IntValue(n) => println!("int value: {}", n),
fidl_lib::JsonValue::StringValue(s) => println!("string: {}", s),
fidl_lib::JsonValueUnknown!() => println!("<unknown union>"),
};
}
```
## Update Source Code {#step-1}
### Dart {#dart-1}
- Replace the unknown tag with a default case in any switch statements
```diff
void useUnion(fidllib.JsonValue value) {
switch (value.$tag) {
case fidllib.JsonValueTag.intValue:
print('int value: ${value.intValue}');
break;
case fidllib.JsonValueTag.stringValue:
print('string value: ${value.stringValue}');
break;
- case fidllib.JsonValueTag.$unknown:
+ default:
+ // Note: unknown variants will fail to decode until the union is marked flexible
print('unknown variant: ${value.$unknownData}');
break;
}
}
```
### Go {#go-1}
- Remove usages of any flexible union specific APIs
```diff
func useUnion(value lib.JsonValue) {
switch value.Which() {
case lib.JsonValueIntValue:
fmt.Printf("int value: %d\n", value.IntValue)
case lib.JsonValueStringValue:
fmt.Printf("string value: %s\n", value.StringValue)
- case lib.JsonValue_unknownData:
- fmt.Printf("unknown data: %+v\n", value.GetUnknownData())
default:
fmt.Println("<unknown tag>")
}
}
```
### HLCPP {#hlcpp-1}
- Replace the `kUnknown` tag with a default case in any switch statements
- Remove usages of any flexible union specific APIs
```diff
void use_union(fidl_test::JsonValue value) {
switch (value.Which()) {
case fidl_test::JsonValue::Tag::kIntValue:
printf("int value: %d\n", value.int_value());
break;
case fidl_test::JsonValue::Tag::kStringValue:
printf("string value: %s\n", value.string_value().c_str());
break;
case fidl_test::JsonValue::Tag::Invalid:
printf("<uninitialized union>\n");
break;
- case fidl_test::JsonValue::Tag::kUnknown:
- printf("<%lu unknown bytes>\n", value.UnknownBytes()->size());
- break;
+ default:
+ printf("<unknown variant>\n");
}
}
```
### LLCPP {#llcpp-1}
- Replace the `kUnknown` tag with a default case in any switch statements
- Remove usages of any flexible union specific APIs
```diff
void use_union(fidl_test::wire::JsonValue* value) {
switch (value->which()) {
case fidl_test::wire::JsonValue::Tag::kIntValue:
printf("int value: %d\n", value->int_value());
break;
case fidl_test::wire::JsonValue::Tag::kStringValue:
printf("string value: %s\n", value->string_value().data());
break;
- case fidl_test::wire::JsonValue::Tag::kUnknown:
- printf("<unknown data>\n");
- break;
+ default:
+ printf("<unknown variant>\n");
}
}
```
### Rust {#rust-1}
- Add `[allow(unreachable_patterns)]` and an underscore arm to match statements on the union
```diff
fn use_union(value: &fidl_lib::JsonValue) {
+ #[allow(unreachable_patterns)]
match value {
fidl_lib::JsonValue::IntValue(n) => println!("int value: {}", n),
fidl_lib::JsonValue::StringValue(s) => println!("string: {}", s),
- fidl_lib::JsonValueUnknown!() => println!("<unknown union>"),
+ _ => {}
};
}
```
## Update FIDL Library {#step-2}
- Change the union from `flexible` to `strict`
```diff
- type JsonValue = flexible union {
+ type JsonValue = strict union {
1: int_value int32;
2: string_value string:MAX;
};
```
## Update Source Code {#step-3}
### Dart {#dart-3}
- You can now remove the default case in any switch statements
```diff
void useUnion(fidllib.JsonValue value) {
+ assert(value.$unknownData == null);
switch (value.$tag) {
case fidllib.JsonValueTag.intValue:
print('int value: ${value.intValue}');
break;
case fidllib.JsonValueTag.stringValue:
print('string value: ${value.stringValue}');
break;
- default:
- // Note: unknown variants will fail to decode until the union is marked flexible
- print('unknown variant: ${value.$unknownData}');
- break;
}
}
```
### HLCPP {#hlcpp-3}
- You can now remove the default case
```diff
void use_union(fidl_test::JsonValue value) {
switch (value.Which()) {
case fidl_test::JsonValue::Tag::kIntValue:
printf("int value: %d\n", value.int_value());
break;
case fidl_test::JsonValue::Tag::kStringValue:
printf("string value: %s\n", value.string_value().c_str());
break;
case fidl_test::JsonValue::Tag::Invalid:
printf("<uninitialized union>\n");
break;
- default:
- printf("<unknown variant>\n");
}
}
```
### LLCPP {#llcpp-3}
- You can now remove the default case
```diff
void use_union(fidl_test::wire::JsonValue* value) {
switch (value->which()) {
case fidl_test::wire::JsonValue::Tag::kIntValue:
printf("int value: %d\n", value->int_value());
break;
case fidl_test::wire::JsonValue::Tag::kStringValue:
printf("string value: %s\n", value->string_value().data());
break;
- default:
- printf("<unknown variant>\n");
}
}
```
### Rust {#rust-3}
- Remove the attribute and underscore arm
```diff
fn use_union(value: &fidl_lib::JsonValue) {
- #[allow(unreachable_patterns)]
match value {
fidl_lib::JsonValue::IntValue(n) => println!("int value: {}", n),
fidl_lib::JsonValue::StringValue(s) => println!("string: {}", s),
- _ => {}
};
}
```