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/legacy_test.go b/internal/impl/legacy_test.go
index 4df07a3..2333fc5 100644
--- a/internal/impl/legacy_test.go
+++ b/internal/impl/legacy_test.go
@@ -831,11 +831,8 @@
 	}
 	for i, xt := range extensions {
 		var got interface{}
-		v := fs.Get(xt.Number())
-		if xt.Cardinality() != pref.Repeated && xt.Kind() == pref.MessageKind {
-			got = v.Interface()
-		} else {
-			got = xt.InterfaceOf(v) // TODO: Simplify this if InterfaceOf allows nil
+		if v := fs.Get(xt.Number()); v.IsValid() {
+			got = xt.InterfaceOf(v)
 		}
 		want := defaultValues[i]
 		if diff := cmp.Diff(want, got, opts); diff != "" {
@@ -924,9 +921,16 @@
 	}
 
 	// Clear the field for all extension types.
-	for _, xt := range extensions {
+	for _, xt := range extensions[:len(extensions)/2] {
 		fs.Clear(xt.Number())
 	}
+	for i, xt := range extensions[len(extensions)/2:] {
+		if i%2 == 0 {
+			fs.Clear(xt.Number())
+		} else {
+			fs.Get(xt.Number()).List().Truncate(0)
+		}
+	}
 	if n := fs.Len(); n != 0 {
 		t.Errorf("KnownFields.Len() = %v, want 0", n)
 	}