internal/impl: pass *coderFieldInfo into fast-path functions
Refactor the fast-path size, marshal, unmarshal, and isinit functions to
take the *coderFieldInfo for the field as input.
This replaces a number of closures capturing field-specific information
with functions taking that information as an explicit parameter.
Change-Id: I8cb39701265edb7b673f6f04a0152d5f4dbb4d5d
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/218937
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/internal/impl/codec_message.go b/internal/impl/codec_message.go
index 24a87a0..cd4ebe6 100644
--- a/internal/impl/codec_message.go
+++ b/internal/impl/codec_message.go
@@ -35,13 +35,15 @@
type coderFieldInfo struct {
funcs pointerCoderFuncs // fast-path per-field functions
- validation validationInfo // information used by message validation
- num pref.FieldNumber // field number
- offset offset // struct field offset
- wiretag uint64 // field tag (number + wire type)
- tagsize int // size of the varint-encoded tag
- isPointer bool // true if IsNil may be called on the struct field
- isRequired bool // true if field is required
+ mi *MessageInfo // field's message
+ ft reflect.Type
+ validation validationInfo // information used by message validation
+ num pref.FieldNumber // field number
+ offset offset // struct field offset
+ wiretag uint64 // field tag (number + wire type)
+ tagsize int // size of the varint-encoded tag
+ isPointer bool // true if IsNil may be called on the struct field
+ isRequired bool // true if field is required
}
func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) {
@@ -67,6 +69,7 @@
}
var fieldOffset offset
var funcs pointerCoderFuncs
+ var childMessage *MessageInfo
switch {
case fd.ContainingOneof() != nil:
fieldOffset = offsetOf(fs, mi.Exporter)
@@ -75,14 +78,16 @@
funcs = makeWeakMessageFieldCoder(fd)
default:
fieldOffset = offsetOf(fs, mi.Exporter)
- funcs = fieldCoder(fd, ft)
+ childMessage, funcs = fieldCoder(fd, ft)
}
cf := &coderFieldInfo{
num: fd.Number(),
offset: fieldOffset,
wiretag: wiretag,
+ ft: ft,
tagsize: wire.SizeVarint(wiretag),
funcs: funcs,
+ mi: childMessage,
validation: newFieldValidationInfo(mi, si, fd, ft),
isPointer: (fd.Cardinality() == pref.Repeated ||
fd.Kind() == pref.MessageKind ||