10 "sort" |
10 "sort" |
11 |
11 |
12 "google.golang.org/protobuf/encoding/protowire" |
12 "google.golang.org/protobuf/encoding/protowire" |
13 "google.golang.org/protobuf/internal/encoding/messageset" |
13 "google.golang.org/protobuf/internal/encoding/messageset" |
14 "google.golang.org/protobuf/internal/order" |
14 "google.golang.org/protobuf/internal/order" |
15 pref "google.golang.org/protobuf/reflect/protoreflect" |
15 "google.golang.org/protobuf/reflect/protoreflect" |
16 piface "google.golang.org/protobuf/runtime/protoiface" |
16 "google.golang.org/protobuf/runtime/protoiface" |
17 ) |
17 ) |
18 |
18 |
19 // coderMessageInfo contains per-message information used by the fast-path functions. |
19 // coderMessageInfo contains per-message information used by the fast-path functions. |
20 // This is a different type from MessageInfo to keep MessageInfo as general-purpose as |
20 // This is a different type from MessageInfo to keep MessageInfo as general-purpose as |
21 // possible. |
21 // possible. |
22 type coderMessageInfo struct { |
22 type coderMessageInfo struct { |
23 methods piface.Methods |
23 methods protoiface.Methods |
24 |
24 |
25 orderedCoderFields []*coderFieldInfo |
25 orderedCoderFields []*coderFieldInfo |
26 denseCoderFields []*coderFieldInfo |
26 denseCoderFields []*coderFieldInfo |
27 coderFields map[protowire.Number]*coderFieldInfo |
27 coderFields map[protowire.Number]*coderFieldInfo |
28 sizecacheOffset offset |
28 sizecacheOffset offset |
36 |
36 |
37 type coderFieldInfo struct { |
37 type coderFieldInfo struct { |
38 funcs pointerCoderFuncs // fast-path per-field functions |
38 funcs pointerCoderFuncs // fast-path per-field functions |
39 mi *MessageInfo // field's message |
39 mi *MessageInfo // field's message |
40 ft reflect.Type |
40 ft reflect.Type |
41 validation validationInfo // information used by message validation |
41 validation validationInfo // information used by message validation |
42 num pref.FieldNumber // field number |
42 num protoreflect.FieldNumber // field number |
43 offset offset // struct field offset |
43 offset offset // struct field offset |
44 wiretag uint64 // field tag (number + wire type) |
44 wiretag uint64 // field tag (number + wire type) |
45 tagsize int // size of the varint-encoded tag |
45 tagsize int // size of the varint-encoded tag |
46 isPointer bool // true if IsNil may be called on the struct field |
46 isPointer bool // true if IsNil may be called on the struct field |
47 isRequired bool // true if field is required |
47 isRequired bool // true if field is required |
48 } |
48 } |
49 |
49 |
50 func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) { |
50 func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) { |
51 mi.sizecacheOffset = invalidOffset |
51 mi.sizecacheOffset = invalidOffset |
52 mi.unknownOffset = invalidOffset |
52 mi.unknownOffset = invalidOffset |
123 ft: ft, |
123 ft: ft, |
124 tagsize: protowire.SizeVarint(wiretag), |
124 tagsize: protowire.SizeVarint(wiretag), |
125 funcs: funcs, |
125 funcs: funcs, |
126 mi: childMessage, |
126 mi: childMessage, |
127 validation: newFieldValidationInfo(mi, si, fd, ft), |
127 validation: newFieldValidationInfo(mi, si, fd, ft), |
128 isPointer: fd.Cardinality() == pref.Repeated || fd.HasPresence(), |
128 isPointer: fd.Cardinality() == protoreflect.Repeated || fd.HasPresence(), |
129 isRequired: fd.Cardinality() == pref.Required, |
129 isRequired: fd.Cardinality() == protoreflect.Required, |
130 } |
130 } |
131 mi.orderedCoderFields = append(mi.orderedCoderFields, cf) |
131 mi.orderedCoderFields = append(mi.orderedCoderFields, cf) |
132 mi.coderFields[cf.num] = cf |
132 mi.coderFields[cf.num] = cf |
133 } |
133 } |
134 for i, oneofs := 0, mi.Desc.Oneofs(); i < oneofs.Len(); i++ { |
134 for i, oneofs := 0, mi.Desc.Oneofs(); i < oneofs.Len(); i++ { |
147 } |
147 } |
148 sort.Slice(mi.orderedCoderFields, func(i, j int) bool { |
148 sort.Slice(mi.orderedCoderFields, func(i, j int) bool { |
149 return mi.orderedCoderFields[i].num < mi.orderedCoderFields[j].num |
149 return mi.orderedCoderFields[i].num < mi.orderedCoderFields[j].num |
150 }) |
150 }) |
151 |
151 |
152 var maxDense pref.FieldNumber |
152 var maxDense protoreflect.FieldNumber |
153 for _, cf := range mi.orderedCoderFields { |
153 for _, cf := range mi.orderedCoderFields { |
154 if cf.num >= 16 && cf.num >= 2*maxDense { |
154 if cf.num >= 16 && cf.num >= 2*maxDense { |
155 break |
155 break |
156 } |
156 } |
157 maxDense = cf.num |
157 maxDense = cf.num |
173 }) |
173 }) |
174 } |
174 } |
175 |
175 |
176 mi.needsInitCheck = needsInitCheck(mi.Desc) |
176 mi.needsInitCheck = needsInitCheck(mi.Desc) |
177 if mi.methods.Marshal == nil && mi.methods.Size == nil { |
177 if mi.methods.Marshal == nil && mi.methods.Size == nil { |
178 mi.methods.Flags |= piface.SupportMarshalDeterministic |
178 mi.methods.Flags |= protoiface.SupportMarshalDeterministic |
179 mi.methods.Marshal = mi.marshal |
179 mi.methods.Marshal = mi.marshal |
180 mi.methods.Size = mi.size |
180 mi.methods.Size = mi.size |
181 } |
181 } |
182 if mi.methods.Unmarshal == nil { |
182 if mi.methods.Unmarshal == nil { |
183 mi.methods.Flags |= piface.SupportUnmarshalDiscardUnknown |
183 mi.methods.Flags |= protoiface.SupportUnmarshalDiscardUnknown |
184 mi.methods.Unmarshal = mi.unmarshal |
184 mi.methods.Unmarshal = mi.unmarshal |
185 } |
185 } |
186 if mi.methods.CheckInitialized == nil { |
186 if mi.methods.CheckInitialized == nil { |
187 mi.methods.CheckInitialized = mi.checkInitialized |
187 mi.methods.CheckInitialized = mi.checkInitialized |
188 } |
188 } |