...

Source file src/google.golang.org/protobuf/internal/impl/convert_list.go

Documentation: google.golang.org/protobuf/internal/impl

     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  func newListConverter(t reflect.Type, fd protoreflect.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) protoreflect.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 protoreflect.ValueOfList(&listReflect{pv, c.c})
    36  }
    37  
    38  func (c *listConverter) GoValueOf(v protoreflect.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 protoreflect.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() protoreflect.Value {
    59  	return protoreflect.ValueOfList(&listReflect{reflect.New(c.goType), c.c})
    60  }
    61  
    62  func (c *listConverter) Zero() protoreflect.Value {
    63  	return protoreflect.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) protoreflect.Value {
    72  	if v.Type() != c.goType {
    73  		panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
    74  	}
    75  	return protoreflect.ValueOfList(&listReflect{v, c.c})
    76  }
    77  
    78  func (c *listPtrConverter) GoValueOf(v protoreflect.Value) reflect.Value {
    79  	return v.List().(*listReflect).v
    80  }
    81  
    82  func (c *listPtrConverter) IsValidPB(v protoreflect.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() protoreflect.Value {
    95  	return c.PBValueOf(reflect.New(c.goType.Elem()))
    96  }
    97  
    98  func (c *listPtrConverter) Zero() protoreflect.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) protoreflect.Value {
   114  	return ls.conv.PBValueOf(ls.v.Elem().Index(i))
   115  }
   116  func (ls *listReflect) Set(i int, v protoreflect.Value) {
   117  	ls.v.Elem().Index(i).Set(ls.conv.GoValueOf(v))
   118  }
   119  func (ls *listReflect) Append(v protoreflect.Value) {
   120  	ls.v.Elem().Set(reflect.Append(ls.v.Elem(), ls.conv.GoValueOf(v)))
   121  }
   122  func (ls *listReflect) AppendMutable() protoreflect.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() protoreflect.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  }
   142  

View as plain text