1*1c12ee1eSDan Willemsen// Copyright 2018 The Go Authors. All rights reserved. 2*1c12ee1eSDan Willemsen// Use of this source code is governed by a BSD-style 3*1c12ee1eSDan Willemsen// license that can be found in the LICENSE file. 4*1c12ee1eSDan Willemsen 5*1c12ee1eSDan Willemsenpackage impl 6*1c12ee1eSDan Willemsen 7*1c12ee1eSDan Willemsenimport ( 8*1c12ee1eSDan Willemsen "fmt" 9*1c12ee1eSDan Willemsen "reflect" 10*1c12ee1eSDan Willemsen 11*1c12ee1eSDan Willemsen "google.golang.org/protobuf/reflect/protoreflect" 12*1c12ee1eSDan Willemsen) 13*1c12ee1eSDan Willemsen 14*1c12ee1eSDan Willemsentype mapConverter struct { 15*1c12ee1eSDan Willemsen goType reflect.Type // map[K]V 16*1c12ee1eSDan Willemsen keyConv, valConv Converter 17*1c12ee1eSDan Willemsen} 18*1c12ee1eSDan Willemsen 19*1c12ee1eSDan Willemsenfunc newMapConverter(t reflect.Type, fd protoreflect.FieldDescriptor) *mapConverter { 20*1c12ee1eSDan Willemsen if t.Kind() != reflect.Map { 21*1c12ee1eSDan Willemsen panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName())) 22*1c12ee1eSDan Willemsen } 23*1c12ee1eSDan Willemsen return &mapConverter{ 24*1c12ee1eSDan Willemsen goType: t, 25*1c12ee1eSDan Willemsen keyConv: newSingularConverter(t.Key(), fd.MapKey()), 26*1c12ee1eSDan Willemsen valConv: newSingularConverter(t.Elem(), fd.MapValue()), 27*1c12ee1eSDan Willemsen } 28*1c12ee1eSDan Willemsen} 29*1c12ee1eSDan Willemsen 30*1c12ee1eSDan Willemsenfunc (c *mapConverter) PBValueOf(v reflect.Value) protoreflect.Value { 31*1c12ee1eSDan Willemsen if v.Type() != c.goType { 32*1c12ee1eSDan Willemsen panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) 33*1c12ee1eSDan Willemsen } 34*1c12ee1eSDan Willemsen return protoreflect.ValueOfMap(&mapReflect{v, c.keyConv, c.valConv}) 35*1c12ee1eSDan Willemsen} 36*1c12ee1eSDan Willemsen 37*1c12ee1eSDan Willemsenfunc (c *mapConverter) GoValueOf(v protoreflect.Value) reflect.Value { 38*1c12ee1eSDan Willemsen return v.Map().(*mapReflect).v 39*1c12ee1eSDan Willemsen} 40*1c12ee1eSDan Willemsen 41*1c12ee1eSDan Willemsenfunc (c *mapConverter) IsValidPB(v protoreflect.Value) bool { 42*1c12ee1eSDan Willemsen mapv, ok := v.Interface().(*mapReflect) 43*1c12ee1eSDan Willemsen if !ok { 44*1c12ee1eSDan Willemsen return false 45*1c12ee1eSDan Willemsen } 46*1c12ee1eSDan Willemsen return mapv.v.Type() == c.goType 47*1c12ee1eSDan Willemsen} 48*1c12ee1eSDan Willemsen 49*1c12ee1eSDan Willemsenfunc (c *mapConverter) IsValidGo(v reflect.Value) bool { 50*1c12ee1eSDan Willemsen return v.IsValid() && v.Type() == c.goType 51*1c12ee1eSDan Willemsen} 52*1c12ee1eSDan Willemsen 53*1c12ee1eSDan Willemsenfunc (c *mapConverter) New() protoreflect.Value { 54*1c12ee1eSDan Willemsen return c.PBValueOf(reflect.MakeMap(c.goType)) 55*1c12ee1eSDan Willemsen} 56*1c12ee1eSDan Willemsen 57*1c12ee1eSDan Willemsenfunc (c *mapConverter) Zero() protoreflect.Value { 58*1c12ee1eSDan Willemsen return c.PBValueOf(reflect.Zero(c.goType)) 59*1c12ee1eSDan Willemsen} 60*1c12ee1eSDan Willemsen 61*1c12ee1eSDan Willemsentype mapReflect struct { 62*1c12ee1eSDan Willemsen v reflect.Value // map[K]V 63*1c12ee1eSDan Willemsen keyConv Converter 64*1c12ee1eSDan Willemsen valConv Converter 65*1c12ee1eSDan Willemsen} 66*1c12ee1eSDan Willemsen 67*1c12ee1eSDan Willemsenfunc (ms *mapReflect) Len() int { 68*1c12ee1eSDan Willemsen return ms.v.Len() 69*1c12ee1eSDan Willemsen} 70*1c12ee1eSDan Willemsenfunc (ms *mapReflect) Has(k protoreflect.MapKey) bool { 71*1c12ee1eSDan Willemsen rk := ms.keyConv.GoValueOf(k.Value()) 72*1c12ee1eSDan Willemsen rv := ms.v.MapIndex(rk) 73*1c12ee1eSDan Willemsen return rv.IsValid() 74*1c12ee1eSDan Willemsen} 75*1c12ee1eSDan Willemsenfunc (ms *mapReflect) Get(k protoreflect.MapKey) protoreflect.Value { 76*1c12ee1eSDan Willemsen rk := ms.keyConv.GoValueOf(k.Value()) 77*1c12ee1eSDan Willemsen rv := ms.v.MapIndex(rk) 78*1c12ee1eSDan Willemsen if !rv.IsValid() { 79*1c12ee1eSDan Willemsen return protoreflect.Value{} 80*1c12ee1eSDan Willemsen } 81*1c12ee1eSDan Willemsen return ms.valConv.PBValueOf(rv) 82*1c12ee1eSDan Willemsen} 83*1c12ee1eSDan Willemsenfunc (ms *mapReflect) Set(k protoreflect.MapKey, v protoreflect.Value) { 84*1c12ee1eSDan Willemsen rk := ms.keyConv.GoValueOf(k.Value()) 85*1c12ee1eSDan Willemsen rv := ms.valConv.GoValueOf(v) 86*1c12ee1eSDan Willemsen ms.v.SetMapIndex(rk, rv) 87*1c12ee1eSDan Willemsen} 88*1c12ee1eSDan Willemsenfunc (ms *mapReflect) Clear(k protoreflect.MapKey) { 89*1c12ee1eSDan Willemsen rk := ms.keyConv.GoValueOf(k.Value()) 90*1c12ee1eSDan Willemsen ms.v.SetMapIndex(rk, reflect.Value{}) 91*1c12ee1eSDan Willemsen} 92*1c12ee1eSDan Willemsenfunc (ms *mapReflect) Mutable(k protoreflect.MapKey) protoreflect.Value { 93*1c12ee1eSDan Willemsen if _, ok := ms.valConv.(*messageConverter); !ok { 94*1c12ee1eSDan Willemsen panic("invalid Mutable on map with non-message value type") 95*1c12ee1eSDan Willemsen } 96*1c12ee1eSDan Willemsen v := ms.Get(k) 97*1c12ee1eSDan Willemsen if !v.IsValid() { 98*1c12ee1eSDan Willemsen v = ms.NewValue() 99*1c12ee1eSDan Willemsen ms.Set(k, v) 100*1c12ee1eSDan Willemsen } 101*1c12ee1eSDan Willemsen return v 102*1c12ee1eSDan Willemsen} 103*1c12ee1eSDan Willemsenfunc (ms *mapReflect) Range(f func(protoreflect.MapKey, protoreflect.Value) bool) { 104*1c12ee1eSDan Willemsen iter := mapRange(ms.v) 105*1c12ee1eSDan Willemsen for iter.Next() { 106*1c12ee1eSDan Willemsen k := ms.keyConv.PBValueOf(iter.Key()).MapKey() 107*1c12ee1eSDan Willemsen v := ms.valConv.PBValueOf(iter.Value()) 108*1c12ee1eSDan Willemsen if !f(k, v) { 109*1c12ee1eSDan Willemsen return 110*1c12ee1eSDan Willemsen } 111*1c12ee1eSDan Willemsen } 112*1c12ee1eSDan Willemsen} 113*1c12ee1eSDan Willemsenfunc (ms *mapReflect) NewValue() protoreflect.Value { 114*1c12ee1eSDan Willemsen return ms.valConv.New() 115*1c12ee1eSDan Willemsen} 116*1c12ee1eSDan Willemsenfunc (ms *mapReflect) IsValid() bool { 117*1c12ee1eSDan Willemsen return !ms.v.IsNil() 118*1c12ee1eSDan Willemsen} 119*1c12ee1eSDan Willemsenfunc (ms *mapReflect) protoUnwrap() interface{} { 120*1c12ee1eSDan Willemsen return ms.v.Interface() 121*1c12ee1eSDan Willemsen} 122