1package jsonprovider
2
3import (
4	"encoding/json"
5
6	"github.com/hashicorp/terraform/internal/configs/configschema"
7	"github.com/zclconf/go-cty/cty"
8)
9
10type attribute struct {
11	AttributeType       json.RawMessage `json:"type,omitempty"`
12	AttributeNestedType *nestedType     `json:"nested_type,omitempty"`
13	Description         string          `json:"description,omitempty"`
14	DescriptionKind     string          `json:"description_kind,omitempty"`
15	Deprecated          bool            `json:"deprecated,omitempty"`
16	Required            bool            `json:"required,omitempty"`
17	Optional            bool            `json:"optional,omitempty"`
18	Computed            bool            `json:"computed,omitempty"`
19	Sensitive           bool            `json:"sensitive,omitempty"`
20}
21
22type nestedType struct {
23	Attributes  map[string]*attribute `json:"attributes,omitempty"`
24	NestingMode string                `json:"nesting_mode,omitempty"`
25	MinItems    uint64                `json:"min_items,omitempty"`
26	MaxItems    uint64                `json:"max_items,omitempty"`
27}
28
29func marshalStringKind(sk configschema.StringKind) string {
30	switch sk {
31	default:
32		return "plain"
33	case configschema.StringMarkdown:
34		return "markdown"
35	}
36}
37
38func marshalAttribute(attr *configschema.Attribute) *attribute {
39	ret := &attribute{
40		Description:     attr.Description,
41		DescriptionKind: marshalStringKind(attr.DescriptionKind),
42		Required:        attr.Required,
43		Optional:        attr.Optional,
44		Computed:        attr.Computed,
45		Sensitive:       attr.Sensitive,
46		Deprecated:      attr.Deprecated,
47	}
48
49	// we're not concerned about errors because at this point the schema has
50	// already been checked and re-checked.
51	if attr.Type != cty.NilType {
52		attrTy, _ := attr.Type.MarshalJSON()
53		ret.AttributeType = attrTy
54	}
55
56	if attr.NestedType != nil {
57		nestedTy := nestedType{
58			MinItems:    uint64(attr.NestedType.MinItems),
59			MaxItems:    uint64(attr.NestedType.MaxItems),
60			NestingMode: nestingModeString(attr.NestedType.Nesting),
61		}
62		attrs := make(map[string]*attribute, len(attr.NestedType.Attributes))
63		for k, attr := range attr.NestedType.Attributes {
64			attrs[k] = marshalAttribute(attr)
65		}
66		nestedTy.Attributes = attrs
67		ret.AttributeNestedType = &nestedTy
68	}
69
70	return ret
71}
72