Skip to content

Commit fe20e07

Browse files
committed
various fixes for netconf project
1 parent e4ae371 commit fe20e07

File tree

9 files changed

+158
-35
lines changed

9 files changed

+158
-35
lines changed

node/selection.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,8 @@ func (sel *Selection) set(r *FieldRequest, hnd *ValueHandle) error {
621621
return nil
622622
}
623623

624-
// GetValue let's you get the leaf value as a Value instance. Returns null if value is null
624+
// Get let's you get the leaf value as a Value instance. Returns null if value is null
625+
// Returns error if path is not found.
625626
func (sel *Selection) Get() (val.Value, error) {
626627
if !meta.IsLeaf(sel.Path.Meta) {
627628
return nil, fmt.Errorf("%s is not a leaf", sel.Path.Meta.Ident())
@@ -640,6 +641,16 @@ func (sel *Selection) Get() (val.Value, error) {
640641
return hnd.Val, err
641642
}
642643

644+
// GetValue let's you get the leaf value at the specified path or ident. Returns null if
645+
// value is null. Returns error if path is not found.
646+
func (sel *Selection) GetValue(pathOrIdent string) (val.Value, error) {
647+
s, err := sel.Find(pathOrIdent)
648+
if err != nil {
649+
return nil, err
650+
}
651+
return s.Get()
652+
}
653+
643654
func (sel *Selection) get(r *FieldRequest, hnd *ValueHandle, useDefault bool) error {
644655
if proceed, constraintErr := sel.Constraints.CheckFieldPreConstraints(r, hnd); !proceed || constraintErr != nil {
645656
return constraintErr

node/value.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ func NewValue(typ *meta.Type, v interface{}) (val.Value, error) {
6565
}
6666
switch typ.Format() {
6767
case val.FmtIdentityRef:
68-
6968
return toIdentRef(typ.Base(), v)
7069
case val.FmtIdentityRefList:
7170
return toIdentRefList(typ.Base(), v)
@@ -78,6 +77,8 @@ func NewValue(typ *meta.Type, v interface{}) (val.Value, error) {
7877
return cvt, err
7978
case val.FmtUnionList:
8079
return toUnionList(typ, v)
80+
case val.FmtLeafRef, val.FmtLeafRefList:
81+
return NewValue(typ.Resolve(), v)
8182
}
8283
return val.Conv(typ.Format(), v)
8384
}

nodeutil/json_rdr.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ func JsonContainerReader(container map[string]interface{}) node.Node {
134134
}
135135
s.OnChild = func(r node.ChildRequest) (child node.Node, e error) {
136136
if r.New {
137-
panic("Cannot write to JSON reader")
137+
panic("cannot write to JSON reader")
138138
}
139139
if value, found := fqkGet(r.Meta, container); found {
140140
if meta.IsList(r.Meta) {
@@ -146,7 +146,7 @@ func JsonContainerReader(container map[string]interface{}) node.Node {
146146
}
147147
s.OnField = func(r node.FieldRequest, hnd *node.ValueHandle) (err error) {
148148
if r.Write {
149-
panic("Cannot write to JSON reader")
149+
panic("cannot write to JSON reader")
150150
}
151151
if val, found := fqkGet(r.Meta, container); found {
152152
hnd.Val, err = leafOrLeafListJsonReader(r.Meta, val)

nodeutil/node.go

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package nodeutil
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
67
"reflect"
78
"sort"
@@ -151,6 +152,10 @@ type Node struct {
151152
// an rpc input.
152153
OnNewObject func(t reflect.Type, m meta.Definition, insideList bool) (reflect.Value, error)
153154

155+
// OnNewNode is called when a new node needs to be created whether it is a child node of
156+
// an rpc i/o or notification event.
157+
OnNewNode func(n *Node, m meta.Meta, obj any) (node.Node, error)
158+
154159
OnContext func(n *Node, s *node.Selection) context.Context
155160

156161
c reflectContainer // internal handler based on object type to handle containers and leafs
@@ -291,7 +296,7 @@ func (n *Node) DoAction(r node.ActionRequest) (node.Node, error) {
291296
if err != nil {
292297
return nil, err
293298
}
294-
return a.do(n, r.Input)
299+
return a.do(n, r.Meta, r.Input)
295300
}
296301

297302
func (n *Node) Notify(r node.NotifyRequest) (node.NotifyCloser, error) {
@@ -343,6 +348,18 @@ func (ref *Node) exists(m meta.Definition) bool {
343348
if found != nil && cerr == nil {
344349
return true
345350
}
351+
} else if meta.IsChoice(m) {
352+
cs, cerr := ref.Choose(nil, m.(*meta.Choice))
353+
if cs != nil && cerr == nil {
354+
// getting a case def might be the default case and not evidence
355+
// data actually exists so we need to recurse into the case defs
356+
for _, ddef := range cs.DataDefinitions() {
357+
if ref.exists(ddef) {
358+
return true
359+
}
360+
}
361+
return true
362+
}
346363
} else {
347364
r := node.FieldRequest{Meta: m.(meta.Leafable)}
348365
var hnd node.ValueHandle
@@ -466,10 +483,10 @@ func (ref *Node) DoNewChild(r node.ChildRequest) (node.Node, error) {
466483
return nil, err
467484
}
468485
if meta.IsList(r.Meta) && r.Selection.Path.Meta != r.Meta {
469-
return ref.NewList(obj.Interface(), ref.onListUpdate(r.Meta.(*meta.List)))
486+
return ref.NewList(r.Meta, obj.Interface(), ref.onListUpdate(r.Meta.(*meta.List)))
470487
}
471488

472-
return ref.New(obj.Interface()), nil
489+
return ref.New(r.Meta, obj.Interface())
473490
}
474491

475492
func (ref *Node) onListUpdate(m *meta.List) NodeListUpdate {
@@ -508,30 +525,42 @@ func (ref *Node) DoGetChild(r node.ChildRequest) (node.Node, error) {
508525
return nil, nil
509526
}
510527
if meta.IsList(r.Meta) && r.Selection.Path.Meta != r.Meta {
511-
return ref.NewList(obj.Interface(), ref.onListUpdate(r.Meta.(*meta.List)))
528+
return ref.NewList(r.Meta, obj.Interface(), ref.onListUpdate(r.Meta.(*meta.List)))
512529
}
513-
return ref.New(obj.Interface()), nil
530+
return ref.New(r.Meta, obj.Interface())
514531
}
515532

516-
func (ref *Node) NewList(obj any, u NodeListUpdate) (*Node, error) {
517-
copy := ref.New(obj)
518-
var err error
519-
copy.l, err = ref.newListHandler(reflect.ValueOf(obj), u)
533+
func (ref *Node) NewList(m meta.Meta, obj any, u NodeListUpdate) (node.Node, error) {
534+
n, err := ref.New(m, obj)
520535
if err != nil {
521536
return nil, err
522537
}
523-
return copy, nil
538+
if copy, isCopy := n.(*Node); isCopy {
539+
var err error
540+
copy.l, err = ref.newListHandler(reflect.ValueOf(obj), u)
541+
if err != nil {
542+
return nil, err
543+
}
544+
}
545+
return n, nil
546+
}
547+
548+
func (ref *Node) New(m meta.Meta, obj any) (node.Node, error) {
549+
if ref.OnNewNode != nil {
550+
return ref.OnNewNode(ref, m, obj)
551+
}
552+
return ref.DoNewNode(m, obj)
524553
}
525554

526-
func (ref *Node) New(obj any) *Node {
555+
func (ref *Node) DoNewNode(m meta.Meta, obj any) (*Node, error) {
527556
if _, isVal := obj.(reflect.Value); isVal {
528-
panic("passing in reflect.Value and not true obj")
557+
return nil, errors.New("passing in reflect.Value and not true obj")
529558
}
530559
copy := *ref
531560
copy.Object = obj
532561
copy.l = nil
533562
copy.c = nil
534-
return &copy
563+
return &copy, nil
535564
}
536565

537566
type reflectContainer interface {
@@ -587,7 +616,7 @@ func (ref *Node) DoGetByKey(r node.ListRequest) (node.Node, error) {
587616
if err != nil || !item.IsValid() || item.IsNil() {
588617
return nil, err
589618
}
590-
return ref.New(item.Interface()), nil
619+
return ref.New(r.Meta, item.Interface())
591620
}
592621

593622
func (ref *Node) DoGetByRow(r node.ListRequest) (node.Node, []val.Value, error) {
@@ -605,7 +634,8 @@ func (ref *Node) DoGetByRow(r node.ListRequest) (node.Node, []val.Value, error)
605634
}
606635
}
607636
}
608-
return ref.New(item.Interface()), key, nil
637+
n, err := ref.New(r.Meta, item.Interface())
638+
return n, key, err
609639

610640
}
611641

@@ -618,7 +648,7 @@ func (ref *Node) DoNewListItem(r node.ListRequest) (node.Node, error) {
618648
if err != nil || !item.IsValid() || item.IsNil() {
619649
return nil, err
620650
}
621-
return ref.New(item.Interface()), nil
651+
return ref.New(r.Meta, item.Interface())
622652
}
623653

624654
func (ref *Node) getValue(v val.Value) any {

nodeutil/node_action.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,17 @@ func newActionHandler(src reflect.Value, rpc *meta.Rpc, opts NodeOptions) (*acti
3333
return def, nil
3434
}
3535

36-
func (def *actionHandler) do(n *Node, in *node.Selection) (node.Node, error) {
36+
func (def *actionHandler) do(n *Node, m *meta.Rpc, in *node.Selection) (node.Node, error) {
3737
inVal, err := def.newInput(in != nil)
3838
if err != nil {
3939
return nil, err
4040
}
4141
if in != nil {
42-
if err = in.UpsertInto(n.New(inVal.Interface())); err != nil {
42+
inNode, err := n.New(m.Input(), inVal.Interface())
43+
if err != nil {
44+
return nil, err
45+
}
46+
if err = in.UpsertInto(inNode); err != nil {
4347
return nil, err
4448
}
4549
}
@@ -49,7 +53,7 @@ func (def *actionHandler) do(n *Node, in *node.Selection) (node.Node, error) {
4953
}
5054

5155
if respVal.IsValid() {
52-
return n.New(respVal.Interface()), nil
56+
return n.New(m.Output(), respVal.Interface())
5357
}
5458

5559
return nil, nil

nodeutil/node_slice.go

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ func newSliceAsList(ref *Node, src reflect.Value, u NodeListUpdate) *sliceAsList
2424
}
2525

2626
func (def *sliceAsList) getByKey(r node.ListRequest) (reflect.Value, error) {
27-
row, v, err := def.findByKey(r.Key, r.Meta.KeyMeta())
27+
row, v, err := def.findByKey(r.Meta, r.Key, r.Meta.KeyMeta())
2828
if row < 0 || err != nil {
2929
return v, err
3030
}
@@ -40,17 +40,20 @@ func (def *sliceAsList) getByRow(r node.ListRequest) (reflect.Value, []reflect.V
4040
if !v.IsValid() || v.IsZero() {
4141
return empty, nil, nil
4242
}
43-
key, _, err := def.getKey(v, r.Meta.KeyMeta())
43+
key, _, err := def.getKey(v, r.Meta, r.Meta.KeyMeta())
4444
return v, key, err
4545
}
4646

47-
func (def *sliceAsList) getKey(item reflect.Value, keyMeta []meta.Leafable) ([]reflect.Value, []val.Value, error) {
47+
func (def *sliceAsList) getKey(item reflect.Value, m meta.Meta, keyMeta []meta.Leafable) ([]reflect.Value, []val.Value, error) {
4848
if len(keyMeta) == 0 || reflectIsEmpty(item) {
4949
return nil, nil, nil
5050
}
5151

5252
// construct mock field requests to get key so we ensure we consult the correct customizations
53-
ref2 := def.ref.New(item.Interface())
53+
ref2, err := def.ref.New(m, item.Interface())
54+
if err != nil {
55+
return nil, nil, fmt.Errorf("%w attempting to get key", err)
56+
}
5457
rvKey := make([]reflect.Value, len(keyMeta))
5558
nvKey := make([]val.Value, len(keyMeta))
5659
for i, kmeta := range keyMeta {
@@ -61,12 +64,19 @@ func (def *sliceAsList) getKey(item reflect.Value, keyMeta []meta.Leafable) ([]r
6164
return nil, nil, fmt.Errorf("%w when get key", err)
6265
}
6366
nvKey[i] = hnd.Val
64-
rvKey[i] = reflect.ValueOf(ref2.getValue(hnd.Val))
67+
switch x := ref2.(type) {
68+
case *Node:
69+
// use opts to help coerse value to right
70+
rvKey[i] = reflect.ValueOf(x.getValue(hnd.Val))
71+
default:
72+
// not a *Node, so just use value directly and trust it's right type
73+
rvKey[i] = reflect.ValueOf(hnd.Val.Value())
74+
}
6575
}
6676
return rvKey, nvKey, nil
6777
}
6878

69-
func (def *sliceAsList) findByKey(target []val.Value, keyMeta []meta.Leafable) (int, reflect.Value, error) {
79+
func (def *sliceAsList) findByKey(m meta.Meta, target []val.Value, keyMeta []meta.Leafable) (int, reflect.Value, error) {
7080
notfound := -1
7181
var empty reflect.Value
7282
// full table scan of items in list to find first item that matches key. consider replacing
@@ -77,7 +87,7 @@ func (def *sliceAsList) findByKey(target []val.Value, keyMeta []meta.Leafable) (
7787
if !candidate.IsValid() {
7888
return notfound, empty, fmt.Errorf("row %d of %T is invalid", row, def.src.Type())
7989
}
80-
_, candidateKey, err := def.getKey(candidate, keyMeta)
90+
_, candidateKey, err := def.getKey(candidate, m, keyMeta)
8191
if err != nil {
8292
return notfound, empty, err
8393
}
@@ -95,7 +105,7 @@ func (def *sliceAsList) findByKey(target []val.Value, keyMeta []meta.Leafable) (
95105
}
96106

97107
func (def *sliceAsList) deleteByKey(r node.ListRequest) error {
98-
row, _, err := def.findByKey(r.Key, r.Meta.KeyMeta())
108+
row, _, err := def.findByKey(r.Meta, r.Key, r.Meta.KeyMeta())
99109
if row < 0 || err != nil {
100110
return err
101111
}

nodeutil/schema2.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func (api schema2) manage(obj any) node.Node {
6464
return n, nil
6565
case "dataDef":
6666
if x, isChoice := n.Object.(*meta.Choice); isChoice {
67-
return n.NewList(x.Cases(), nil)
67+
return n.NewList(r.Meta, x.Cases(), nil)
6868
}
6969
hasDefs := n.Object.(meta.HasDataDefinitions)
7070
if hasRecursiveChild(hasDefs) {
@@ -77,7 +77,7 @@ func (api schema2) manage(obj any) node.Node {
7777
copy[i] = defs[i]
7878
}
7979
}
80-
return n.NewList(copy, nil)
80+
return n.NewList(r.Meta, copy, nil)
8181
}
8282
case "unique":
8383
if x, ok := n.Object.(*meta.List); ok {
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
module "module"
2+
[ident] "refine"
3+
{ "{"
4+
grouping "grouping"
5+
[ident] "g1"
6+
{ "{"
7+
uses "uses"
8+
[ident] "g2"
9+
; ";"
10+
} "}"
11+
grouping "grouping"
12+
[ident] "g2"
13+
{ "{"
14+
uses "uses"
15+
[ident] "g3"
16+
{ "{"
17+
augment "augment"
18+
[string] "\"t1/t2\""
19+
{ "{"
20+
leaf "leaf"
21+
[ident] "l2"
22+
{ "{"
23+
description "descriptio"...
24+
[string] "\"orig\""
25+
; ";"
26+
type "type"
27+
[ident] "string"
28+
; ";"
29+
} "}"
30+
} "}"
31+
} "}"
32+
} "}"
33+
grouping "grouping"
34+
[ident] "g3"
35+
{ "{"
36+
choice "choice"
37+
[ident] "t1"
38+
{ "{"
39+
case "case"
40+
[ident] "t2"
41+
{ "{"
42+
leaf "leaf"
43+
[ident] "l1"
44+
{ "{"
45+
type "type"
46+
[ident] "string"
47+
; ";"
48+
} "}"
49+
} "}"
50+
} "}"
51+
} "}"
52+
notification "notificati"...
53+
[ident] "c"
54+
{ "{"
55+
uses "uses"
56+
[ident] "g1"
57+
{ "{"
58+
refine "refine"
59+
[string] "\"t1/t2/l2\""
60+
{ "{"
61+
description "descriptio"...
62+
[string] "\"here\""
63+
; ";"
64+
} "}"
65+
} "}"
66+
} "}"
67+
} "}"

0 commit comments

Comments
 (0)