all: tests, tweaks for lazy extension decoding
Add a test to confirm that extensions are lazily decoded when we expect.
Drop the UnmarshalDefaultResolver flag. I added it thinking for some
reason that internal/impl couldn't depend on protoregistry; since it can
(and does), it's simpler to just test if the resolver is the expected
value.
Use a default set of options when lazily unmarshaling extensions.
Change-Id: Ied7666ffdc3bf90630260a80c9568d9a945048bc
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/218038
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/internal/impl/codec_extension.go b/internal/impl/codec_extension.go
index 1098159..efeea2f 100644
--- a/internal/impl/codec_extension.go
+++ b/internal/impl/codec_extension.go
@@ -136,7 +136,7 @@
wtyp := wire.Type(tag & 7)
var out unmarshalOutput
var err error
- val, out, err = f.lazy.xi.funcs.unmarshal(b, val, num, wtyp, unmarshalOptions{})
+ val, out, err = f.lazy.xi.funcs.unmarshal(b, val, num, wtyp, lazyUnmarshalOptions)
if err != nil {
panic(errors.New("decode failure in lazy extension decoding: %v", err))
}
@@ -227,3 +227,34 @@
return f.typ.ValueOf(fn())
})
}
+
+// IsLazy reports whether a field is lazily encoded.
+// It is exported for testing.
+func IsLazy(m pref.Message, fd pref.FieldDescriptor) bool {
+ var mi *MessageInfo
+ var p pointer
+ switch m := m.(type) {
+ case *messageState:
+ mi = m.messageInfo()
+ p = m.pointer()
+ case *messageReflectWrapper:
+ mi = m.messageInfo()
+ p = m.pointer()
+ default:
+ return false
+ }
+ xd, ok := fd.(pref.ExtensionTypeDescriptor)
+ if !ok {
+ return false
+ }
+ xt := xd.Type()
+ ext := mi.extensionMap(p)
+ if ext == nil {
+ return false
+ }
+ f, ok := (*ext)[int32(fd.Number())]
+ if !ok {
+ return false
+ }
+ return f.typ == xt && f.lazy != nil && atomic.LoadUint32(&f.lazy.atomicOnce) == 0
+}