map.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // Copyright 2018 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package value
  5. import (
  6. "reflect"
  7. pref "google.golang.org/protobuf/reflect/protoreflect"
  8. )
  9. // MapOf returns a protoreflect.Map view of p, which must a *map[K]V.
  10. // If p is nil, this returns an empty, read-only map.
  11. func MapOf(p interface{}, kc, kv Converter) interface {
  12. pref.Map
  13. Unwrapper
  14. } {
  15. // TODO: Validate that p is a *map[K]V?
  16. rv := reflect.ValueOf(p)
  17. return &mapReflect{rv, kc, kv}
  18. }
  19. type mapReflect struct {
  20. v reflect.Value // *map[K]V
  21. keyConv Converter
  22. valConv Converter
  23. }
  24. func (ms *mapReflect) Len() int {
  25. if ms.v.IsNil() {
  26. return 0
  27. }
  28. return ms.v.Elem().Len()
  29. }
  30. func (ms *mapReflect) Has(k pref.MapKey) bool {
  31. if ms.v.IsNil() {
  32. return false
  33. }
  34. rk := ms.keyConv.GoValueOf(k.Value())
  35. rv := ms.v.Elem().MapIndex(rk)
  36. return rv.IsValid()
  37. }
  38. func (ms *mapReflect) Get(k pref.MapKey) pref.Value {
  39. if ms.v.IsNil() {
  40. return pref.Value{}
  41. }
  42. rk := ms.keyConv.GoValueOf(k.Value())
  43. rv := ms.v.Elem().MapIndex(rk)
  44. if !rv.IsValid() {
  45. return pref.Value{}
  46. }
  47. return ms.valConv.PBValueOf(rv)
  48. }
  49. func (ms *mapReflect) Set(k pref.MapKey, v pref.Value) {
  50. if ms.v.Elem().IsNil() {
  51. ms.v.Elem().Set(reflect.MakeMap(ms.v.Elem().Type()))
  52. }
  53. rk := ms.keyConv.GoValueOf(k.Value())
  54. rv := ms.valConv.GoValueOf(v)
  55. ms.v.Elem().SetMapIndex(rk, rv)
  56. }
  57. func (ms *mapReflect) Clear(k pref.MapKey) {
  58. rk := ms.keyConv.GoValueOf(k.Value())
  59. ms.v.Elem().SetMapIndex(rk, reflect.Value{})
  60. }
  61. func (ms *mapReflect) Range(f func(pref.MapKey, pref.Value) bool) {
  62. if ms.v.IsNil() {
  63. return
  64. }
  65. for _, k := range ms.v.Elem().MapKeys() {
  66. if v := ms.v.Elem().MapIndex(k); v.IsValid() {
  67. pk := ms.keyConv.PBValueOf(k).MapKey()
  68. pv := ms.valConv.PBValueOf(v)
  69. if !f(pk, pv) {
  70. return
  71. }
  72. }
  73. }
  74. }
  75. func (ms *mapReflect) NewMessage() pref.Message {
  76. return ms.valConv.NewMessage()
  77. }
  78. func (ms *mapReflect) ProtoUnwrap() interface{} {
  79. return ms.v.Interface()
  80. }