hashicorp / hashicorp/terraform-plugin-framework
types: Consider Preventing Missing AttrTypes/ElemType from Object and Collection Types
- Dominant language
- Go
- Stars
- 384
- Forks
- 107
- Avg merge
- 3m
- Merged PRs (30d)
- 1
Description
### Module version
```
v1.3.0
```
### Use-cases
Since the framework's inception, the element type of a collection type, such as `types.ListType`, `types.MapType`, and `types.SetType`, and the attribute types of a `types.ObjectType` have been managed by an exported Go struct type field on each:
```go
types.ListType{
ElemType: /* ... */,
}
types.MapType{
ElemType: /* ... */,
}
types.ObjectType{
AttrTypes: map[string]attr.Type{/* ... */},
}
types.SetType{
ElemType: /* ... */,
}
```
The issue is that the Go compiler cannot provide any sort of warnings to provider developers if those fields are omitted, therefore making the type definition invalid. While the framework can provide some helpful unit testing helpers to try and catch this before its caught as a provider server runtime error, it would be more helpful for developers if this situation wasn't possible at all. There are already value creation functions in the `types/basetypes`, but nothing for type creation.
### Attempted Solutions
A developer could manually create a helper function to prevent this now, e.g. as a quick sketch
```go
func NewListType(elemType attr.Type) types.ListType {
return types.ListType{
ElemType: elemType,
}
}
```
However it would be up to those developers how to enforce usage.
### Proposal
Proposals in this case need to cover two separate aspects:
- How to create types safely (e.g. functions, etc.)
- How to _prevent_ unsafe type create (e.g. breaking changes such as deprecating/removing the exported `ElemType` field)
One potential option in this space is implementing something like the above, but potentially doing the breaking changes all at once, especially in the `types` package:
```go
package types
func ListType(elemType attr.Type) basetypes.ListType {
return basetypes.NewListType(elemType)
}
package basetypes
type ListType struct {
elemType attr.Type
}
func NewListType(elemType attr.Type) ListType {
return ListType{
elemType: elemType,
}
}
```
### References
- #714
- #755
Contributor guide
Assessment
This issue has not been assessed yet.