-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcomposite.go
More file actions
57 lines (47 loc) · 2.54 KB
/
composite.go
File metadata and controls
57 lines (47 loc) · 2.54 KB
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
package protopath
import (
"github.com/daishe/protoreflectextra"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
"github.com/daishe/protopath/internal/genid"
)
// composite is a wrapper of any composite protocol buffer type (message, list or map) allowing easy traversal and operations.
type composite interface {
// IsReadOnly reports wether underlying composite value is read only.
IsReadOnly() bool
// Self returns underlying composite value. For messages it returns its protoreflect.Message value. For lists and maps it returns List and Map interfaces accordingly.
Self() any
// Get returns value associated with the given field / index / key. It returns error if the field / index / key is not found. For scalar types and messages it returns its value. For lists and maps it returns List and Map interfaces accordingly.
Get(s Segment) (any, error)
// Mutable is a mutable variant of Get method - it returns value associated with the given field / index / key. It returns error if the underlying composite value is read-only or the field / index / key is not found. For scalar types and messages it returns its value. For lists and maps it returns List and Map interfaces accordingly.
Mutable(s Segment) (any, error)
// Access descends into the given field / index / key and returns that value. It returns error if the field / index / key is not found or is not associated with a composite type.
Access(s Segment) (any, error)
// AccessMutable is a mutable variant of Access method - it descends into the given field / index / key and returns that value. It returns error if the underlying composite value is read-only, if the field / index / key is not found or is not associated with a composite type.
AccessMutable(s Segment) (any, error)
}
func newComposite(x any) composite {
switch x := x.(type) {
case protoreflectextra.List:
return newGenericListComposite(x)
case protoreflectextra.Map:
return newGenericMapComposite(x)
case proto.Message:
return newMessageComposite(x.ProtoReflect())
case protoreflect.Message:
return newMessageComposite(x)
}
return nil
}
func newMessageComposite(m protoreflect.Message) composite {
switch m.Descriptor().FullName() { // must have a case for each massage based composite implementation
case genid.Value_message_fullname:
return newValueComposite(m)
case genid.Struct_message_fullname:
return newStructComposite(m)
case genid.ListValue_message_fullname:
return newListValueComposite(m)
default: // generic proto message
return newGenericMessageComposite(m)
}
}