convert_list.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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) New() pref.Value {
  30. return c.PBValueOf(reflect.New(c.goType.Elem()))
  31. }
  32. func (c *listConverter) Zero() pref.Value {
  33. return c.PBValueOf(reflect.Zero(c.goType))
  34. }
  35. type listReflect struct {
  36. v reflect.Value // *[]T
  37. conv Converter
  38. }
  39. func (ls *listReflect) Len() int {
  40. if ls.v.IsNil() {
  41. return 0
  42. }
  43. return ls.v.Elem().Len()
  44. }
  45. func (ls *listReflect) Get(i int) pref.Value {
  46. return ls.conv.PBValueOf(ls.v.Elem().Index(i))
  47. }
  48. func (ls *listReflect) Set(i int, v pref.Value) {
  49. ls.v.Elem().Index(i).Set(ls.conv.GoValueOf(v))
  50. }
  51. func (ls *listReflect) Append(v pref.Value) {
  52. ls.v.Elem().Set(reflect.Append(ls.v.Elem(), ls.conv.GoValueOf(v)))
  53. }
  54. func (ls *listReflect) Truncate(i int) {
  55. ls.v.Elem().Set(ls.v.Elem().Slice(0, i))
  56. }
  57. func (ls *listReflect) NewMessage() pref.Message {
  58. return ls.NewElement().Message()
  59. }
  60. func (ls *listReflect) NewElement() pref.Value {
  61. return ls.conv.New()
  62. }
  63. func (ls *listReflect) ProtoUnwrap() interface{} {
  64. return ls.v.Interface()
  65. }