vendor/google.golang.org/protobuf/internal/impl/convert_list.go
changeset 256 6d9efbef00a9
child 260 445e01aede7e
equal deleted inserted replaced
255:4f153a23adab 256:6d9efbef00a9
       
     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 	pref "google.golang.org/protobuf/reflect/protoreflect"
       
    12 )
       
    13 
       
    14 func newListConverter(t reflect.Type, fd pref.FieldDescriptor) Converter {
       
    15 	switch {
       
    16 	case t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Slice:
       
    17 		return &listPtrConverter{t, newSingularConverter(t.Elem().Elem(), fd)}
       
    18 	case t.Kind() == reflect.Slice:
       
    19 		return &listConverter{t, newSingularConverter(t.Elem(), fd)}
       
    20 	}
       
    21 	panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName()))
       
    22 }
       
    23 
       
    24 type listConverter struct {
       
    25 	goType reflect.Type // []T
       
    26 	c      Converter
       
    27 }
       
    28 
       
    29 func (c *listConverter) PBValueOf(v reflect.Value) pref.Value {
       
    30 	if v.Type() != c.goType {
       
    31 		panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
       
    32 	}
       
    33 	pv := reflect.New(c.goType)
       
    34 	pv.Elem().Set(v)
       
    35 	return pref.ValueOfList(&listReflect{pv, c.c})
       
    36 }
       
    37 
       
    38 func (c *listConverter) GoValueOf(v pref.Value) reflect.Value {
       
    39 	rv := v.List().(*listReflect).v
       
    40 	if rv.IsNil() {
       
    41 		return reflect.Zero(c.goType)
       
    42 	}
       
    43 	return rv.Elem()
       
    44 }
       
    45 
       
    46 func (c *listConverter) IsValidPB(v pref.Value) bool {
       
    47 	list, ok := v.Interface().(*listReflect)
       
    48 	if !ok {
       
    49 		return false
       
    50 	}
       
    51 	return list.v.Type().Elem() == c.goType
       
    52 }
       
    53 
       
    54 func (c *listConverter) IsValidGo(v reflect.Value) bool {
       
    55 	return v.IsValid() && v.Type() == c.goType
       
    56 }
       
    57 
       
    58 func (c *listConverter) New() pref.Value {
       
    59 	return pref.ValueOfList(&listReflect{reflect.New(c.goType), c.c})
       
    60 }
       
    61 
       
    62 func (c *listConverter) Zero() pref.Value {
       
    63 	return pref.ValueOfList(&listReflect{reflect.Zero(reflect.PtrTo(c.goType)), c.c})
       
    64 }
       
    65 
       
    66 type listPtrConverter struct {
       
    67 	goType reflect.Type // *[]T
       
    68 	c      Converter
       
    69 }
       
    70 
       
    71 func (c *listPtrConverter) PBValueOf(v reflect.Value) pref.Value {
       
    72 	if v.Type() != c.goType {
       
    73 		panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
       
    74 	}
       
    75 	return pref.ValueOfList(&listReflect{v, c.c})
       
    76 }
       
    77 
       
    78 func (c *listPtrConverter) GoValueOf(v pref.Value) reflect.Value {
       
    79 	return v.List().(*listReflect).v
       
    80 }
       
    81 
       
    82 func (c *listPtrConverter) IsValidPB(v pref.Value) bool {
       
    83 	list, ok := v.Interface().(*listReflect)
       
    84 	if !ok {
       
    85 		return false
       
    86 	}
       
    87 	return list.v.Type() == c.goType
       
    88 }
       
    89 
       
    90 func (c *listPtrConverter) IsValidGo(v reflect.Value) bool {
       
    91 	return v.IsValid() && v.Type() == c.goType
       
    92 }
       
    93 
       
    94 func (c *listPtrConverter) New() pref.Value {
       
    95 	return c.PBValueOf(reflect.New(c.goType.Elem()))
       
    96 }
       
    97 
       
    98 func (c *listPtrConverter) Zero() pref.Value {
       
    99 	return c.PBValueOf(reflect.Zero(c.goType))
       
   100 }
       
   101 
       
   102 type listReflect struct {
       
   103 	v    reflect.Value // *[]T
       
   104 	conv Converter
       
   105 }
       
   106 
       
   107 func (ls *listReflect) Len() int {
       
   108 	if ls.v.IsNil() {
       
   109 		return 0
       
   110 	}
       
   111 	return ls.v.Elem().Len()
       
   112 }
       
   113 func (ls *listReflect) Get(i int) pref.Value {
       
   114 	return ls.conv.PBValueOf(ls.v.Elem().Index(i))
       
   115 }
       
   116 func (ls *listReflect) Set(i int, v pref.Value) {
       
   117 	ls.v.Elem().Index(i).Set(ls.conv.GoValueOf(v))
       
   118 }
       
   119 func (ls *listReflect) Append(v pref.Value) {
       
   120 	ls.v.Elem().Set(reflect.Append(ls.v.Elem(), ls.conv.GoValueOf(v)))
       
   121 }
       
   122 func (ls *listReflect) AppendMutable() pref.Value {
       
   123 	if _, ok := ls.conv.(*messageConverter); !ok {
       
   124 		panic("invalid AppendMutable on list with non-message type")
       
   125 	}
       
   126 	v := ls.NewElement()
       
   127 	ls.Append(v)
       
   128 	return v
       
   129 }
       
   130 func (ls *listReflect) Truncate(i int) {
       
   131 	ls.v.Elem().Set(ls.v.Elem().Slice(0, i))
       
   132 }
       
   133 func (ls *listReflect) NewElement() pref.Value {
       
   134 	return ls.conv.New()
       
   135 }
       
   136 func (ls *listReflect) IsValid() bool {
       
   137 	return !ls.v.IsNil()
       
   138 }
       
   139 func (ls *listReflect) protoUnwrap() interface{} {
       
   140 	return ls.v.Interface()
       
   141 }