internal/impl: allow reflection on typed nil pointers

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>
diff --git a/internal/value/list.go b/internal/value/list.go
index dadb05f..bcac98b 100644
--- a/internal/value/list.go
+++ b/internal/value/list.go
@@ -15,41 +15,44 @@
 	Unwrapper
 } {
 	// TODO: Validate that p is a *[]T?
-	rv := reflect.ValueOf(p).Elem()
+	rv := reflect.ValueOf(p)
 	return listReflect{rv, c}
 }
 
 type listReflect struct {
-	v    reflect.Value // addressable []T
+	v    reflect.Value // *[]T
 	conv Converter
 }
 
 func (ls listReflect) Len() int {
-	return ls.v.Len()
+	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.Index(i))
+	return ls.conv.PBValueOf(ls.v.Elem().Index(i))
 }
 func (ls listReflect) Set(i int, v pref.Value) {
-	ls.v.Index(i).Set(ls.conv.GoValueOf(v))
+	ls.v.Elem().Index(i).Set(ls.conv.GoValueOf(v))
 }
 func (ls listReflect) Append(v pref.Value) {
-	ls.v.Set(reflect.Append(ls.v, ls.conv.GoValueOf(v)))
+	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.Index(i)).Message()
+	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.Set(reflect.Append(ls.v, ls.conv.GoValueOf(pv)))
+	ls.v.Elem().Set(reflect.Append(ls.v.Elem(), ls.conv.GoValueOf(pv)))
 	return pv.Message()
 }
 func (ls listReflect) Truncate(i int) {
-	ls.v.Set(ls.v.Slice(0, i))
+	ls.v.Elem().Set(ls.v.Elem().Slice(0, i))
 }
 func (ls listReflect) ProtoUnwrap() interface{} {
-	return ls.v.Addr().Interface()
+	return ls.v.Interface()
 }
 func (ls listReflect) ProtoMutable() {}