Feature: Increased support for defaults in tables
- Dominant language
- C++
- Stars
- 26.5k
- Forks
- 3.7k
- PR merge metrics
- No merged PRs in 30d
Description
# Motivation
This feature requests schema-specifiable defaults for all fields in tables. After this feature and #6014 are implemented, **schema writers will have full control over the semantics of non-presence for all fields in tables :)** Table fields may be optional (and non presence maps to None) or not (and non-presence maps to some default value).
As was the case with #6014, we should only do this if we have sufficient buy-in to get all major languages to add these features in a small time window, which means we won't get around to implementing this until after we're done with #6014. But there's no harm discussing this now.
### High Level
Schema writers may specify:
- Empty defaults for ~tables and~ vectors, anything more complex seems challenging.
- Default empty tables doesn't seem to add that much benefit and may break/complicate the object API if there are cycles
- Static strings for strings.
- ~Static variants for unions, but the default variant's table is empty.~
- We're not doing default empty tables.
- ~Static structs for structs. Parsing a struct in the schema will be complex, but doable.~
- Turns out parser support is kinda hard. We'll revisit this if there's interest
Generated readers must return the specified default if a field is non-present. Generated builders must leave the field non-present if asked to write a default value. The generated type must not be optional.
## Example Schema:
https://github.com/google/flatbuffers/blob/master/tests/more_defaults.fbs
```
enum ABC: int { A, B, C }
table MoreDefaults {
ints: [int] = [];
floats: [float] = [ ];
empty_string: string = "";
some_string: string = "some";
abcs: [ABC] = [];
bools: [bool] = [];
}
```
When reading this table
- if a vector field is not present in binary, it must be read as an empty vector
- if a string field is not present in binary, it must be read as the default provided string
- when writing an empty vector or default string to binary, it should not be written at all (i.e. vtable offset set to 0)
- The accessor's return types must not be optionally typed.
- E.g. in Rust the accessor `fn ints(&self) -> &[i32]` does not return an `Option<&[i32]>`
- the native object's field types must not be optionally typed
- E.g. in Rust, the field `some_string: String` rather than `Option`.
## TODO
| task | owner | done
|---|---|--|
| Parser support | @caspern | #6421 |
| Rust support | @caspern | #6421 |
| C++ support | @vglavnyy ?
| Java support | @paulovap ?
| kotlin support | @paulovap ?
| Swift support | @mustiikhalil | #6461
| lobster support | @aardappel ?
| C support| @mikkelfj ?
| C# support | @dbaileychess ?
| TS/JS support | @krojew ?
| Documentation updates | @CasperN
Contributor guide
Assessment
This issue has not been assessed yet.