33
44package hclwrite
55
6+ import (
7+ "github.com/hashicorp/hcl/v2"
8+ "github.com/hashicorp/hcl/v2/hclsyntax"
9+ "github.com/zclconf/go-cty/cty"
10+ )
11+
612type ObjectConsExpr struct {
713 inTree
14+
15+ items nodeSet
816}
917
1018func newObjectConsExpr () * ObjectConsExpr {
1119 return & ObjectConsExpr {
1220 inTree : newInTree (),
21+ items : newNodeSet (),
22+ }
23+ }
24+
25+ func (object * ObjectConsExpr ) firstItemNode () * node {
26+ return object .items .List ()[0 ]
27+ }
28+
29+ // SetItemRaw either replaces the expression of an existing item of the given
30+ // name or adds a new item definition to the end of the object, using the given
31+ // tokens verbatim as the expression.
32+ //
33+ // The same caveats apply to this function as for NewExpressionRaw on which it
34+ // is based. If possible, prefer to use SetItemValue or SetItemTraversal.
35+ func (object * ObjectConsExpr ) SetItemRaw (key string , tokens Tokens ) (* ObjectConsKey , * ObjectConsValue ) {
36+ item := object .ItemFor (key )
37+ expr := NewExpressionRaw (tokens )
38+ if item != nil {
39+ item .valueObj ().expr .Detach ()
40+ item .valueObj ().expr = item .valueObj ().children .Append (expr )
41+ } else {
42+ item = newObjectConsItem ()
43+ item .init (key , expr )
44+ if firstItemNode := object .firstItemNode (); firstItemNode == nil {
45+ return nil , nil
46+ } else {
47+ object .items .Add (object .children .Insert (firstItemNode , item ))
48+ }
1349 }
50+ return item .kv ()
51+ }
52+
53+ // SetItemValue either replaces the expression of an existing item of the given
54+ // name or adds a new item definition to the end of the object.
55+ //
56+ // The value is given as a cty.Value, and must therefore be a literal. To set a
57+ // variable reference or other traversal, use SetItemTraversal.
58+ //
59+ // The return value is the item that was either modified in-place or created.
60+ func (object * ObjectConsExpr ) SetItemValue (name string , val cty.Value ) (* ObjectConsKey , * ObjectConsValue ) {
61+ return nil , nil
1462}
1563
16- func (o * ObjectConsExpr ) ValueFor (key string ) * ObjectConsValue {
17- var found * ObjectConsValue
18- o .walkChildNodes (func (n * node ) {
64+ // SetItemTraversal either replaces the expression of an existing item of the
65+ // given name or adds a new item definition to the end of the object.
66+ //
67+ // The new expression is given as a hcl.Traversal, which must be an absolute
68+ // traversal. To set a literal value, use SetItemValue.
69+ //
70+ // The return value is the item that was either modified in-place or created.
71+ func (object * ObjectConsExpr ) SetItemTraversal (name string , traversal hcl.Traversal ) (* ObjectConsKey , * ObjectConsValue ) {
72+ return nil , nil
73+ }
74+
75+ func (object * ObjectConsExpr ) ItemFor (key string ) * ObjectConsItem {
76+ var found * ObjectConsItem
77+ object .walkChildNodes (func (n * node ) {
1978 if item , ok := n .content .(* ObjectConsItem ); ok {
2079 k := item .key .content .(* ObjectConsKey )
2180 name := k .name .content .(* Expression )
@@ -28,14 +87,22 @@ func (o *ObjectConsExpr) ValueFor(key string) *ObjectConsValue {
2887 }
2988
3089 if k .literal && (maybeKey == key || maybeKey == `"` + key + `"` ) {
31- found = item . value . content .( * ObjectConsValue )
90+ found = item
3291 return
3392 }
3493 }
3594 })
3695 return found
3796}
3897
98+ func (object * ObjectConsExpr ) ValueFor (key string ) * ObjectConsValue {
99+ if item := object .ItemFor (key ); item == nil {
100+ return nil
101+ } else {
102+ return item .value .content .(* ObjectConsValue )
103+ }
104+ }
105+
39106type ObjectConsItem struct {
40107 inTree
41108 key * node
@@ -48,8 +115,42 @@ func newObjectConsItem() *ObjectConsItem {
48115 }
49116}
50117
118+ func (item * ObjectConsItem ) keyObj () * ObjectConsKey {
119+ return item .key .content .(* ObjectConsKey )
120+ }
121+
122+ func (item * ObjectConsItem ) valueObj () * ObjectConsValue {
123+ return item .value .content .(* ObjectConsValue )
124+ }
125+
126+ func (item * ObjectConsItem ) init (key string , value * Expression ) {
127+ value .assertUnattached ()
128+
129+ item .children .AppendUnstructuredTokens (Tokens {
130+ {
131+ Type : hclsyntax .TokenNewline ,
132+ Bytes : []byte {'\n' },
133+ },
134+ })
135+ item .key = item .children .Append (newObjectConsKey ())
136+ item .keyObj ().children .Append (newIdentifier (newIdentToken (key )))
137+
138+ item .children .AppendUnstructuredTokens (Tokens {
139+ {
140+ Type : hclsyntax .TokenEqual ,
141+ Bytes : []byte {'=' },
142+ },
143+ })
144+
145+ item .value = item .children .Append (newObjectConsValue ())
146+ item .valueObj ().children .Append (value )
147+ }
148+
51149func (item * ObjectConsItem ) kv () (* ObjectConsKey , * ObjectConsValue ) {
52- return item .key .content .(* ObjectConsKey ), item .value .content .(* ObjectConsValue )
150+ key := item .key .content .(* ObjectConsKey )
151+ value := item .value .content .(* ObjectConsValue )
152+
153+ return key , value
53154}
54155
55156type ObjectConsKey struct {
0 commit comments