blob: 2eec00736f73befe635778e6bd33f6f0781bfabd [file] [log] [blame]
Joe Tsai4b7aff62018-11-14 14:05:19 -08001// 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
5package value
6
7import (
8 "reflect"
9
10 pref "github.com/golang/protobuf/v2/reflect/protoreflect"
11)
12
13func ListOf(p interface{}, c Converter) pref.List {
14 // TODO: Validate that p is a *[]T?
15 rv := reflect.ValueOf(p).Elem()
16 return listReflect{rv, c}
17}
18
19type listReflect struct {
20 v reflect.Value // addressable []T
21 conv Converter
22}
23
24func (ls listReflect) Len() int {
25 return ls.v.Len()
26}
27func (ls listReflect) Get(i int) pref.Value {
28 return ls.conv.PBValueOf(ls.v.Index(i))
29}
30func (ls listReflect) Set(i int, v pref.Value) {
31 ls.v.Index(i).Set(ls.conv.GoValueOf(v))
32}
33func (ls listReflect) Append(v pref.Value) {
34 ls.v.Set(reflect.Append(ls.v, ls.conv.GoValueOf(v)))
35}
36func (ls listReflect) Mutable(i int) pref.Mutable {
37 // Mutable is only valid for messages and panics for other kinds.
38 rv := ls.v.Index(i)
39 if rv.IsNil() {
40 // TODO: Is checking for nil proper behavior for custom messages?
41 pv := pref.ValueOf(ls.conv.MessageType.New().ProtoReflect())
42 rv.Set(ls.conv.GoValueOf(pv))
43 }
44 return rv.Interface().(pref.Message)
45}
46func (ls listReflect) MutableAppend() pref.Mutable {
47 // MutableAppend is only valid for messages and panics for other kinds.
48 pv := pref.ValueOf(ls.conv.MessageType.New().ProtoReflect())
49 ls.v.Set(reflect.Append(ls.v, ls.conv.GoValueOf(pv)))
50 return ls.v.Index(ls.Len() - 1).Interface().(pref.Message)
51}
52func (ls listReflect) Truncate(i int) {
53 ls.v.Set(ls.v.Slice(0, i))
54}
55func (ls listReflect) Unwrap() interface{} {
56 return ls.v.Addr().Interface()
57}
58func (ls listReflect) ProtoMutable() {}
59
60var (
61 _ pref.List = listReflect{}
62 _ Unwrapper = listReflect{}
63)