proto: add Equal

Add support for basic equality comparison of messages.

Messages are equal if they have the same type and marshal to the
same bytes with deterministic serialization, with some exceptions:

 - Messages with different registered extensions are unequal.
 - NaN is not equal to itself.

Unlike the v1 Equal, a nil message is equal to an empty message of
the same type.

Change-Id: Ibabdadd8c767b801051b8241aeae1ba077e58121
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/174277
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/proto/decode_test.go b/proto/decode_test.go
index 2c95f6b..084014f 100644
--- a/proto/decode_test.go
+++ b/proto/decode_test.go
@@ -16,6 +16,7 @@
 	"github.com/golang/protobuf/v2/internal/scalar"
 	"github.com/golang/protobuf/v2/proto"
 	pref "github.com/golang/protobuf/v2/reflect/protoreflect"
+	"github.com/golang/protobuf/v2/runtime/protolegacy"
 
 	testpb "github.com/golang/protobuf/v2/internal/testprotos/test"
 	test3pb "github.com/golang/protobuf/v2/internal/testprotos/test3"
@@ -1254,6 +1255,13 @@
 	}
 }
 
+func registerExtension(desc *protoV1.ExtensionDesc) buildOpt {
+	return func(m proto.Message) {
+		et := protolegacy.X.ExtensionTypeFromDesc(desc)
+		m.ProtoReflect().KnownFields().ExtensionTypes().Register(et)
+	}
+}
+
 func extend(desc *protoV1.ExtensionDesc, value interface{}) buildOpt {
 	return func(m proto.Message) {
 		if err := protoV1.SetExtension(m.(protoV1.Message), desc, value); err != nil {