Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package gnmi
import (
"fmt"
"strconv"
log "github.com/golang/glog"
"github.com/openconfig/goyang/pkg/yang"
pb "github.com/openconfig/gnmi/proto/gnmi"
)
// getChildNode gets a node's child with corresponding schema specified by path
// element. If not found and createIfNotExist is set as true, an empty node is
// created and returned.
func getChildNode(node map[string]interface{}, schema *yang.Entry, elem *pb.PathElem, createIfNotExist bool) (interface{}, *yang.Entry) {
var nextSchema *yang.Entry
var ok bool
if nextSchema, ok = schema.Dir[elem.Name]; !ok {
return nil, nil
}
var nextNode interface{}
if elem.GetKey() == nil {
if nextNode, ok = node[elem.Name]; !ok {
if createIfNotExist {
node[elem.Name] = make(map[string]interface{})
nextNode = node[elem.Name]
}
}
return nextNode, nextSchema
}
nextNode = getKeyedListEntry(node, elem, createIfNotExist)
return nextNode, nextSchema
}
// getKeyedListEntry finds the keyed list entry in node by the name and key of
// path elem. If entry is not found and createIfNotExist is true, an empty entry
// will be created (the list will be created if necessary).
func getKeyedListEntry(node map[string]interface{}, elem *pb.PathElem, createIfNotExist bool) map[string]interface{} {
curNode, ok := node[elem.Name]
if !ok {
if !createIfNotExist {
return nil
}
// Create a keyed list as node child and initialize an entry.
m := make(map[string]interface{})
for k, v := range elem.Key {
m[k] = v
if vAsNum, err := strconv.ParseFloat(v, 64); err == nil {
m[k] = vAsNum
}
}
node[elem.Name] = []interface{}{m}
return m
}
// Search entry in keyed list.
keyedList, ok := curNode.([]interface{})
if !ok {
return nil
}
for _, n := range keyedList {
m, ok := n.(map[string]interface{})
if !ok {
log.Errorf("wrong keyed list entry type: %T", n)
return nil
}
keyMatching := true
// must be exactly match
for k, v := range elem.Key {
attrVal, ok := m[k]
if !ok {
return nil
}
if v != fmt.Sprintf("%v", attrVal) {
keyMatching = false
break
}
}
if keyMatching {
return m
}
}
if !createIfNotExist {
return nil
}
// Create an entry in keyed list.
m := make(map[string]interface{})
for k, v := range elem.Key {
m[k] = v
if vAsNum, err := strconv.ParseFloat(v, 64); err == nil {
m[k] = vAsNum
}
}
node[elem.Name] = append(keyedList, m)
return m
}