gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

convert_map.go (3102B)


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