proto: fix memory aliasing bug in Reset

Fix a bug where using Message.Range alone does not clear
memory references for empty, but allocated lists and maps.
Thus, we iterate over every known field and explicitly call Clear.

Change-Id: I9c1847d4056cf66f3199947150f3140d0783444a
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/183197
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/proto/reset.go b/proto/reset.go
index fd8b786..f14d9ae 100644
--- a/proto/reset.go
+++ b/proto/reset.go
@@ -14,11 +14,18 @@
 }
 
 func resetMessage(m protoreflect.Message) {
+	// Clear all known fields.
+	fds := m.Descriptor().Fields()
+	for i := 0; i < fds.Len(); i++ {
+		m.Clear(fds.Get(i))
+	}
+
+	// Clear extension fields.
 	m.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool {
 		m.Clear(fd)
 		return true
 	})
-	if m.GetUnknown() != nil {
-		m.SetUnknown(nil)
-	}
+
+	// Clear unknown fields.
+	m.SetUnknown(nil)
 }