2018-11-05 19:42:22 +00:00
|
|
|
// Copyright 2018 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
package value
|
|
|
|
|
|
|
|
import (
|
|
|
|
"reflect"
|
|
|
|
|
|
|
|
pref "github.com/golang/protobuf/v2/reflect/protoreflect"
|
|
|
|
)
|
|
|
|
|
2018-11-29 22:54:05 +00:00
|
|
|
func MapOf(p interface{}, kc, kv Converter) interface {
|
|
|
|
pref.Map
|
|
|
|
Unwrapper
|
|
|
|
} {
|
2018-11-05 19:42:22 +00:00
|
|
|
// TODO: Validate that p is a *map[K]V?
|
2018-12-01 12:57:09 +00:00
|
|
|
rv := reflect.ValueOf(p)
|
2018-11-05 19:42:22 +00:00
|
|
|
return mapReflect{rv, kc, kv}
|
|
|
|
}
|
|
|
|
|
|
|
|
type mapReflect struct {
|
2018-12-01 12:57:09 +00:00
|
|
|
v reflect.Value // *map[K]V
|
2018-11-05 19:42:22 +00:00
|
|
|
keyConv Converter
|
|
|
|
valConv Converter
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ms mapReflect) Len() int {
|
2018-12-01 12:57:09 +00:00
|
|
|
if ms.v.IsNil() {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
return ms.v.Elem().Len()
|
2018-11-05 19:42:22 +00:00
|
|
|
}
|
|
|
|
func (ms mapReflect) Has(k pref.MapKey) bool {
|
2018-12-01 12:57:09 +00:00
|
|
|
if ms.v.IsNil() {
|
|
|
|
return false
|
|
|
|
}
|
2018-11-05 19:42:22 +00:00
|
|
|
rk := ms.keyConv.GoValueOf(k.Value())
|
2018-12-01 12:57:09 +00:00
|
|
|
rv := ms.v.Elem().MapIndex(rk)
|
2018-11-05 19:42:22 +00:00
|
|
|
return rv.IsValid()
|
|
|
|
}
|
|
|
|
func (ms mapReflect) Get(k pref.MapKey) pref.Value {
|
2018-12-01 12:57:09 +00:00
|
|
|
if ms.v.IsNil() {
|
|
|
|
return pref.Value{}
|
|
|
|
}
|
2018-11-05 19:42:22 +00:00
|
|
|
rk := ms.keyConv.GoValueOf(k.Value())
|
2018-12-01 12:57:09 +00:00
|
|
|
rv := ms.v.Elem().MapIndex(rk)
|
2018-11-05 19:42:22 +00:00
|
|
|
if !rv.IsValid() {
|
|
|
|
return pref.Value{}
|
|
|
|
}
|
|
|
|
return ms.valConv.PBValueOf(rv)
|
|
|
|
}
|
|
|
|
func (ms mapReflect) Set(k pref.MapKey, v pref.Value) {
|
2018-12-01 12:57:09 +00:00
|
|
|
if ms.v.Elem().IsNil() {
|
|
|
|
ms.v.Elem().Set(reflect.MakeMap(ms.v.Elem().Type()))
|
2018-11-05 19:42:22 +00:00
|
|
|
}
|
|
|
|
rk := ms.keyConv.GoValueOf(k.Value())
|
|
|
|
rv := ms.valConv.GoValueOf(v)
|
2018-12-01 12:57:09 +00:00
|
|
|
ms.v.Elem().SetMapIndex(rk, rv)
|
2018-11-05 19:42:22 +00:00
|
|
|
}
|
|
|
|
func (ms mapReflect) Clear(k pref.MapKey) {
|
|
|
|
rk := ms.keyConv.GoValueOf(k.Value())
|
2018-12-01 12:57:09 +00:00
|
|
|
ms.v.Elem().SetMapIndex(rk, reflect.Value{})
|
2018-11-05 19:42:22 +00:00
|
|
|
}
|
|
|
|
func (ms mapReflect) Range(f func(pref.MapKey, pref.Value) bool) {
|
2018-12-01 12:57:09 +00:00
|
|
|
if ms.v.IsNil() {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
for _, k := range ms.v.Elem().MapKeys() {
|
|
|
|
if v := ms.v.Elem().MapIndex(k); v.IsValid() {
|
2018-11-05 19:42:22 +00:00
|
|
|
pk := ms.keyConv.PBValueOf(k).MapKey()
|
|
|
|
pv := ms.valConv.PBValueOf(v)
|
|
|
|
if !f(pk, pv) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-01-09 10:57:13 +00:00
|
|
|
func (ms mapReflect) NewMessage() pref.Message {
|
2018-12-07 22:28:33 +00:00
|
|
|
return ms.valConv.MessageType.New()
|
|
|
|
}
|
2018-11-29 22:54:05 +00:00
|
|
|
func (ms mapReflect) ProtoUnwrap() interface{} {
|
2018-12-01 12:57:09 +00:00
|
|
|
return ms.v.Interface()
|
2018-11-05 19:42:22 +00:00
|
|
|
}
|