mirror of
https://github.com/protocolbuffers/protobuf-go.git
synced 2025-02-22 12:39:52 +00:00
Similar to how generated messages allow you to call Get methods on a nil pointer, we permit similar functionality when protobuf reflection is used on a nil pointer. Change-Id: Ie2f596d39105c191073b42d7d689525c3b715240 Reviewed-on: https://go-review.googlesource.com/c/152021 Reviewed-by: Damien Neil <dneil@google.com>
59 lines
1.5 KiB
Go
59 lines
1.5 KiB
Go
// Copyright 2018 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package value
|
|
|
|
import (
|
|
"reflect"
|
|
|
|
pref "github.com/golang/protobuf/v2/reflect/protoreflect"
|
|
)
|
|
|
|
func ListOf(p interface{}, c Converter) interface {
|
|
pref.List
|
|
Unwrapper
|
|
} {
|
|
// TODO: Validate that p is a *[]T?
|
|
rv := reflect.ValueOf(p)
|
|
return listReflect{rv, c}
|
|
}
|
|
|
|
type listReflect struct {
|
|
v reflect.Value // *[]T
|
|
conv Converter
|
|
}
|
|
|
|
func (ls listReflect) Len() int {
|
|
if ls.v.IsNil() {
|
|
return 0
|
|
}
|
|
return ls.v.Elem().Len()
|
|
}
|
|
func (ls listReflect) Get(i int) pref.Value {
|
|
return ls.conv.PBValueOf(ls.v.Elem().Index(i))
|
|
}
|
|
func (ls listReflect) Set(i int, v pref.Value) {
|
|
ls.v.Elem().Index(i).Set(ls.conv.GoValueOf(v))
|
|
}
|
|
func (ls listReflect) Append(v pref.Value) {
|
|
ls.v.Elem().Set(reflect.Append(ls.v.Elem(), ls.conv.GoValueOf(v)))
|
|
}
|
|
func (ls listReflect) Mutable(i int) pref.Mutable {
|
|
// Mutable is only valid for messages and panics for other kinds.
|
|
return ls.conv.PBValueOf(ls.v.Elem().Index(i)).Message()
|
|
}
|
|
func (ls listReflect) MutableAppend() pref.Mutable {
|
|
// MutableAppend is only valid for messages and panics for other kinds.
|
|
pv := pref.ValueOf(ls.conv.MessageType.New().ProtoReflect())
|
|
ls.v.Elem().Set(reflect.Append(ls.v.Elem(), ls.conv.GoValueOf(pv)))
|
|
return pv.Message()
|
|
}
|
|
func (ls listReflect) Truncate(i int) {
|
|
ls.v.Elem().Set(ls.v.Elem().Slice(0, i))
|
|
}
|
|
func (ls listReflect) ProtoUnwrap() interface{} {
|
|
return ls.v.Interface()
|
|
}
|
|
func (ls listReflect) ProtoMutable() {}
|