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/impl/pointer_reflect.go b/internal/impl/pointer_reflect.go
index 6732824..0b62f6c 100644
--- a/internal/impl/pointer_reflect.go
+++ b/internal/impl/pointer_reflect.go
@@ -32,21 +32,33 @@
 }
 
 // pointerOfIface returns the pointer portion of an interface.
-func pointerOfIface(v *interface{}) pointer {
-	return pointer{v: reflect.ValueOf(*v)}
+func pointerOfIface(v interface{}) pointer {
+	return pointer{v: reflect.ValueOf(v)}
 }
 
-// apply adds an offset to the pointer to derive a new pointer
+// IsNil reports whether the pointer is nil.
+func (p pointer) IsNil() bool {
+	return p.v.IsNil()
+}
+
+// Apply adds an offset to the pointer to derive a new pointer
 // to a specified field. The current pointer must be pointing at a struct.
-func (p pointer) apply(f offset) pointer {
+func (p pointer) Apply(f offset) pointer {
 	// TODO: Handle unexported fields in an API that hides XXX fields?
 	return pointer{v: p.v.Elem().FieldByIndex(f).Addr()}
 }
 
-// asType treats p as a pointer to an object of type t and returns the value.
-func (p pointer) asType(t reflect.Type) reflect.Value {
+// AsValueOf treats p as a pointer to an object of type t and returns the value.
+// It is equivalent to reflect.ValueOf(p.AsIfaceOf(t))
+func (p pointer) AsValueOf(t reflect.Type) reflect.Value {
 	if p.v.Type().Elem() != t {
 		panic(fmt.Sprintf("invalid type: got %v, want %v", p.v.Type(), t))
 	}
 	return p.v
 }
+
+// AsIfaceOf treats p as a pointer to an object of type t and returns the value.
+// It is equivalent to p.AsValueOf(t).Interface()
+func (p pointer) AsIfaceOf(t reflect.Type) interface{} {
+	return p.AsValueOf(t).Interface()
+}