internal/impl: weak field bugfixes

Fix a reversed error check in impl.Export{}.WeakNil.

Check to see if we have a type for the weak field on marshal/size.

Treat a typed nil valued in XXX_Weak as not indicating presence for
the field.

Change-Id: Id667ac7eb4f53236be9e181017082bd8cd21d115
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/198717
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/internal/impl/codec_field.go b/internal/impl/codec_field.go
index 45b4664..4cfd9b0 100644
--- a/internal/impl/codec_field.go
+++ b/internal/impl/codec_field.go
@@ -5,6 +5,7 @@
 package impl
 
 import (
+	"fmt"
 	"reflect"
 	"sync"
 
@@ -12,7 +13,6 @@
 	"google.golang.org/protobuf/proto"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
 	preg "google.golang.org/protobuf/reflect/protoregistry"
-	piface "google.golang.org/protobuf/runtime/protoiface"
 )
 
 type errInvalidUTF8 struct{}
@@ -91,47 +91,49 @@
 		})
 	}
 
-	num := int32(fd.Number())
+	num := fd.Number()
 	return pointerCoderFuncs{
 		size: func(p pointer, tagsize int, opts marshalOptions) int {
-			fs := p.WeakFields()
-			m, ok := (*fs)[num]
+			m, ok := p.WeakFields().get(num)
 			if !ok {
 				return 0
 			}
-			return sizeMessage(m.(proto.Message), tagsize, opts)
+			lazyInit()
+			if messageType == nil {
+				panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
+			}
+			return sizeMessage(m, tagsize, opts)
 		},
 		marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
-			fs := p.WeakFields()
-			m, ok := (*fs)[num]
+			m, ok := p.WeakFields().get(num)
 			if !ok {
 				return b, nil
 			}
-			return appendMessage(b, m.(proto.Message), wiretag, opts)
+			lazyInit()
+			if messageType == nil {
+				panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
+			}
+			return appendMessage(b, m, wiretag, opts)
 		},
 		unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, error) {
 			fs := p.WeakFields()
-			m, ok := (*fs)[num]
+			m, ok := fs.get(num)
 			if !ok {
 				lazyInit()
 				if messageType == nil {
 					return 0, errUnknown
 				}
-				m = messageType.New().Interface().(piface.MessageV1)
-				if *fs == nil {
-					*fs = make(WeakFields)
-				}
-				(*fs)[num] = m
+				m = messageType.New().Interface()
+				fs.set(num, m)
 			}
-			return consumeMessage(b, m.(proto.Message), wtyp, opts)
+			return consumeMessage(b, m, wtyp, opts)
 		},
 		isInit: func(p pointer) error {
-			fs := p.WeakFields()
-			m, ok := (*fs)[num]
+			m, ok := p.WeakFields().get(num)
 			if !ok {
 				return nil
 			}
-			return proto.IsInitialized(m.(proto.Message))
+			return proto.IsInitialized(m)
 		},
 	}
 }