convert_list.go 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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 impl
  5. import (
  6. "fmt"
  7. "reflect"
  8. pref "google.golang.org/protobuf/reflect/protoreflect"
  9. )
  10. type listConverter struct {
  11. goType reflect.Type
  12. c Converter
  13. }
  14. func newListConverter(t reflect.Type, fd pref.FieldDescriptor) Converter {
  15. if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Slice {
  16. panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName()))
  17. }
  18. return &listConverter{t, newSingularConverter(t.Elem().Elem(), fd)}
  19. }
  20. func (c *listConverter) PBValueOf(v reflect.Value) pref.Value {
  21. if v.Type() != c.goType {
  22. panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
  23. }
  24. return pref.ValueOf(&listReflect{v, c.c})
  25. }
  26. func (c *listConverter) GoValueOf(v pref.Value) reflect.Value {
  27. return v.List().(*listReflect).v
  28. }
  29. func (c *listConverter) IsValidPB(v pref.Value) bool {
  30. list, ok := v.Interface().(*listReflect)
  31. if !ok {
  32. return false
  33. }
  34. return list.v.Type() == c.goType
  35. }
  36. func (c *listConverter) IsValidGo(v reflect.Value) bool {
  37. return v.Type() == c.goType
  38. }
  39. func (c *listConverter) New() pref.Value {
  40. return c.PBValueOf(reflect.New(c.goType.Elem()))
  41. }
  42. func (c *listConverter) Zero() pref.Value {
  43. return c.PBValueOf(reflect.Zero(c.goType))
  44. }
  45. type listReflect struct {
  46. v reflect.Value // *[]T
  47. conv Converter
  48. }
  49. func (ls *listReflect) Len() int {
  50. if ls.v.IsNil() {
  51. return 0
  52. }
  53. return ls.v.Elem().Len()
  54. }
  55. func (ls *listReflect) Get(i int) pref.Value {
  56. return ls.conv.PBValueOf(ls.v.Elem().Index(i))
  57. }
  58. func (ls *listReflect) Set(i int, v pref.Value) {
  59. ls.v.Elem().Index(i).Set(ls.conv.GoValueOf(v))
  60. }
  61. func (ls *listReflect) Append(v pref.Value) {
  62. ls.v.Elem().Set(reflect.Append(ls.v.Elem(), ls.conv.GoValueOf(v)))
  63. }
  64. func (ls *listReflect) Truncate(i int) {
  65. ls.v.Elem().Set(ls.v.Elem().Slice(0, i))
  66. }
  67. func (ls *listReflect) NewMessage() pref.Message {
  68. return ls.NewElement().Message()
  69. }
  70. func (ls *listReflect) NewElement() pref.Value {
  71. return ls.conv.New()
  72. }
  73. func (ls *listReflect) ProtoUnwrap() interface{} {
  74. return ls.v.Interface()
  75. }