proto, runtime/protoiface: add support for fast-path marshaling
Allow message implementations to provide optimized versions of standard
operations. Generated messages now include a ProtoReflectMethods method,
returning a protoiface.Methods struct containing pointers to assorted
optional functions.
The Methods struct also includes a Flags field indicating support for
optional features such as deterministic marshaling.
Implementation of the fast paths (and tests) will come in later CLs.
Change-Id: Idd1beed0ecf43ec5e5e7b8da2ee1e08d3ce32213
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/170340
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/proto/size.go b/proto/size.go
index 8c9263f..a817cf7 100644
--- a/proto/size.go
+++ b/proto/size.go
@@ -13,9 +13,21 @@
// Size returns the size in bytes of the wire-format encoding of m.
func Size(m Message) int {
+ if size, err := sizeMessageFast(m); err == nil {
+ return size
+ }
return sizeMessage(m.ProtoReflect())
}
+func sizeMessageFast(m Message) (int, error) {
+ // TODO: Pass MarshalOptions to size to permit disabling fast path?
+ methods := protoMethods(m)
+ if methods == nil || methods.Size == nil {
+ return 0, errInternalNoFast
+ }
+ return methods.Size(m), nil
+}
+
func sizeMessage(m protoreflect.Message) (size int) {
fields := m.Type().Fields()
knownFields := m.KnownFields()