internal/impl: treat a nil oneof wrapper as if it were unset

The old implementation had the behavior where a nil wrapper value:
	m := new(foopb.Message)
	m.OneofField = (*foopb.Message_OneofUint32)(nil)
was functionally equivalent to it being directly set to nil:
	m := new(foopb.Message)
	m.OneofField = nil
preserve this semantic in both the table-drive implementation
and the reflection implementation.

Change-Id: Ie44d51e044d4822e61d0e646fbc44aa8d9b90c1f
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/189559
Reviewed-by: Herbie Ong <herbie@google.com>
diff --git a/internal/impl/codec_field.go b/internal/impl/codec_field.go
index 16873e4..af6ce05 100644
--- a/internal/impl/codec_field.go
+++ b/internal/impl/codec_field.go
@@ -30,7 +30,7 @@
 			return pointer{}, false
 		}
 		v = v.Elem() // interface -> *struct
-		if v.Elem().Type() != ot {
+		if v.IsNil() || v.Elem().Type() != ot {
 			return pointer{}, false
 		}
 		return pointerOfValue(v).Apply(zeroOffset), true
diff --git a/internal/impl/message_reflect_field.go b/internal/impl/message_reflect_field.go
index 10cacc7..6f7051b 100644
--- a/internal/impl/message_reflect_field.go
+++ b/internal/impl/message_reflect_field.go
@@ -56,7 +56,7 @@
 				return false
 			}
 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
-			if rv.IsNil() || rv.Elem().Type().Elem() != ot {
+			if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() {
 				return false
 			}
 			return true
@@ -64,6 +64,8 @@
 		clear: func(p pointer) {
 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
 			if rv.IsNil() || rv.Elem().Type().Elem() != ot {
+				// NOTE: We intentionally don't check for rv.Elem().IsNil()
+				// so that (*OneofWrapperType)(nil) gets cleared to nil.
 				return
 			}
 			rv.Set(reflect.Zero(rv.Type()))
@@ -73,7 +75,7 @@
 				return conv.Zero()
 			}
 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
-			if rv.IsNil() || rv.Elem().Type().Elem() != ot {
+			if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() {
 				return conv.Zero()
 			}
 			rv = rv.Elem().Elem().Field(0)
@@ -81,7 +83,7 @@
 		},
 		set: func(p pointer, v pref.Value) {
 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
-			if rv.IsNil() || rv.Elem().Type().Elem() != ot {
+			if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() {
 				rv.Set(reflect.New(ot))
 			}
 			rv = rv.Elem().Elem().Field(0)
@@ -92,7 +94,7 @@
 				panic("invalid Mutable on field with non-composite type")
 			}
 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
-			if rv.IsNil() || rv.Elem().Type().Elem() != ot {
+			if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() {
 				rv.Set(reflect.New(ot))
 			}
 			rv = rv.Elem().Elem().Field(0)