reflect/protoreflect: clarify Get semantics on unpopulated fields

Clearly specify that Get on an unpopulated field:
* returns the default value for scalars
* returns a mutable (but empty) List for repeated fields
* returns a mutable (but empty) Map for map fields
* returns an invalid value for message fields

The difference in semantics between List+Maps and Messages is because
protobuf semantics provide no distinction between an unpopulated and empty list
or map. On the other hand, there is a semantic difference between an unpopulated
message and an empty message.

Default values for scalars is trivial to implement with FieldDescriptor.Default.

A mutable, but empty List and Map is easy to implement for known fields since
known fields are generated as a slice or map field in a struct.
Since struct fields are addressable, the implementation can just return a
reference to the slice or map.

Repeated, extension fields are a little more tricky since extension fields
are implemented under the hood as a map[FieldNumber]Extension.
Rather than allocating an empty list in KnownFields.Get upon first retrieval
(which presents a race), delegate the work to ExtensionFieldTypes.Register,
which must occur before any Get operation. Register is not a concurrent-safe
operation, so that is an excellent time to initilize empty lists.
The implementation of extensions will need to be careful that Clear on a repeated
field simply truncates it zero instead of deleting the object.

For unpopulated messages, we return an invalid value, instead of the prior
behavior of returning a typed nil-pointer to the Go type for the message.
The approach is problematic because it assumes that
1) all messages are always implemented on a pointer reciever
2) a typed nil-pointer is an appropriate "read-only, but empty" message
These assumptions are not true of all message types (e.g., dynamic messages).

Change-Id: Ie96e6744c890308d9de738b6cf01d3b19e7e7c6a
Reviewed-on: https://go-review.googlesource.com/c/150319
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/internal/impl/message_field.go b/internal/impl/message_field.go
index 2686a97..75cf867 100644
--- a/internal/impl/message_field.go
+++ b/internal/impl/message_field.go
@@ -61,9 +61,7 @@
 			rv := p.apply(fieldOffset).asType(fs.Type).Elem()
 			if rv.IsNil() || rv.Elem().Type().Elem() != ot {
 				if fd.Kind() == pref.MessageKind || fd.Kind() == pref.GroupKind {
-					// TODO: Should this return an invalid protoreflect.Value?
-					rv = reflect.Zero(ot.Field(0).Type)
-					return conv.PBValueOf(rv)
+					return pref.Value{}
 				}
 				return fd.Default()
 			}
@@ -96,7 +94,7 @@
 				pv := pref.ValueOf(conv.MessageType.New().ProtoReflect())
 				rv.Set(conv.GoValueOf(pv))
 			}
-			return rv.Interface().(pref.Message)
+			return conv.PBValueOf(rv).Message()
 		},
 	}
 }
@@ -253,19 +251,18 @@
 			return !rv.IsNil()
 		},
 		get: func(p pointer) pref.Value {
-			// TODO: If rv.IsNil(), should this return a typed-nil pointer or
-			// an invalid protoreflect.Value?
-			//
-			// Returning a typed nil pointer assumes that such values
-			// are valid for all possible custom message types,
-			// which may not be case for dynamic messages.
 			rv := p.apply(fieldOffset).asType(fs.Type).Elem()
+			if rv.IsNil() {
+				return pref.Value{}
+			}
 			return conv.PBValueOf(rv)
 		},
 		set: func(p pointer, v pref.Value) {
-			// TODO: Similarly, is it valid to set this to a typed nil pointer?
 			rv := p.apply(fieldOffset).asType(fs.Type).Elem()
 			rv.Set(conv.GoValueOf(v))
+			if rv.IsNil() {
+				panic("invalid nil pointer")
+			}
 		},
 		clear: func(p pointer) {
 			rv := p.apply(fieldOffset).asType(fs.Type).Elem()