hashicorp / hashicorp/terraform-plugin-framework

types: Consider Preventing Missing AttrTypes/ElemType from Object and Collection Types

Open
#761 0 comments 0 reactions 0 assignees View on GitHub
breaking-change enhancement thinking
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.