map.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  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. func MapOf(p interface{}, kc, kv Converter) interface {
  10. pref.Map
  11. Unwrapper
  12. } {
  13. // TODO: Validate that p is a *map[K]V?
  14. rv := reflect.ValueOf(p)
  15. return mapReflect{rv, kc, kv}
  16. }
  17. type mapReflect struct {
  18. v reflect.Value // *map[K]V
  19. keyConv Converter
  20. valConv Converter
  21. }
  22. func (ms mapReflect) Len() int {
  23. if ms.v.IsNil() {
  24. return 0
  25. }
  26. return ms.v.Elem().Len()
  27. }
  28. func (ms mapReflect) Has(k pref.MapKey) bool {
  29. if ms.v.IsNil() {
  30. return false
  31. }
  32. rk := ms.keyConv.GoValueOf(k.Value())
  33. rv := ms.v.Elem().MapIndex(rk)
  34. return rv.IsValid()
  35. }
  36. func (ms mapReflect) Get(k pref.MapKey) pref.Value {
  37. if ms.v.IsNil() {
  38. return pref.Value{}
  39. }
  40. rk := ms.keyConv.GoValueOf(k.Value())
  41. rv := ms.v.Elem().MapIndex(rk)
  42. if !rv.IsValid() {
  43. return pref.Value{}
  44. }
  45. return ms.valConv.PBValueOf(rv)
  46. }
  47. func (ms mapReflect) Set(k pref.MapKey, v pref.Value) {
  48. if ms.v.Elem().IsNil() {
  49. ms.v.Elem().Set(reflect.MakeMap(ms.v.Elem().Type()))
  50. }
  51. rk := ms.keyConv.GoValueOf(k.Value())
  52. rv := ms.valConv.GoValueOf(v)
  53. ms.v.Elem().SetMapIndex(rk, rv)
  54. }
  55. func (ms mapReflect) Clear(k pref.MapKey) {
  56. rk := ms.keyConv.GoValueOf(k.Value())
  57. ms.v.Elem().SetMapIndex(rk, reflect.Value{})
  58. }
  59. func (ms mapReflect) Range(f func(pref.MapKey, pref.Value) bool) {
  60. if ms.v.IsNil() {
  61. return
  62. }
  63. for _, k := range ms.v.Elem().MapKeys() {
  64. if v := ms.v.Elem().MapIndex(k); v.IsValid() {
  65. pk := ms.keyConv.PBValueOf(k).MapKey()
  66. pv := ms.valConv.PBValueOf(v)
  67. if !f(pk, pv) {
  68. return
  69. }
  70. }
  71. }
  72. }
  73. func (ms mapReflect) NewMessage() pref.Message {
  74. return ms.valConv.MessageType.New()
  75. }
  76. func (ms mapReflect) ProtoUnwrap() interface{} {
  77. return ms.v.Interface()
  78. }