mirror of
https://github.com/mudler/luet.git
synced 2025-07-13 07:04:19 +00:00
Instead of using gox on one side and an action to release, we can merge them together with goreleaser which will build for extra targets (arm, mips if needed in the future) and it also takes care of creating checksums, a source archive, and a changelog and creating a release with all the artifacts. All binaries should respect the old naming convention, so any scripts out there should still work. Signed-off-by: Itxaka <igarcia@suse.com>
218 lines
7.0 KiB
Go
218 lines
7.0 KiB
Go
// Copyright 2019 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package impl
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
"sort"
|
|
|
|
"google.golang.org/protobuf/encoding/protowire"
|
|
"google.golang.org/protobuf/internal/encoding/messageset"
|
|
"google.golang.org/protobuf/internal/order"
|
|
pref "google.golang.org/protobuf/reflect/protoreflect"
|
|
piface "google.golang.org/protobuf/runtime/protoiface"
|
|
)
|
|
|
|
// coderMessageInfo contains per-message information used by the fast-path functions.
|
|
// This is a different type from MessageInfo to keep MessageInfo as general-purpose as
|
|
// possible.
|
|
type coderMessageInfo struct {
|
|
methods piface.Methods
|
|
|
|
orderedCoderFields []*coderFieldInfo
|
|
denseCoderFields []*coderFieldInfo
|
|
coderFields map[protowire.Number]*coderFieldInfo
|
|
sizecacheOffset offset
|
|
unknownOffset offset
|
|
unknownPtrKind bool
|
|
extensionOffset offset
|
|
needsInitCheck bool
|
|
isMessageSet bool
|
|
numRequiredFields uint8
|
|
}
|
|
|
|
type coderFieldInfo struct {
|
|
funcs pointerCoderFuncs // fast-path per-field functions
|
|
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) {
|
|
mi.sizecacheOffset = invalidOffset
|
|
mi.unknownOffset = invalidOffset
|
|
mi.extensionOffset = invalidOffset
|
|
|
|
if si.sizecacheOffset.IsValid() && si.sizecacheType == sizecacheType {
|
|
mi.sizecacheOffset = si.sizecacheOffset
|
|
}
|
|
if si.unknownOffset.IsValid() && (si.unknownType == unknownFieldsAType || si.unknownType == unknownFieldsBType) {
|
|
mi.unknownOffset = si.unknownOffset
|
|
mi.unknownPtrKind = si.unknownType.Kind() == reflect.Ptr
|
|
}
|
|
if si.extensionOffset.IsValid() && si.extensionType == extensionFieldsType {
|
|
mi.extensionOffset = si.extensionOffset
|
|
}
|
|
|
|
mi.coderFields = make(map[protowire.Number]*coderFieldInfo)
|
|
fields := mi.Desc.Fields()
|
|
preallocFields := make([]coderFieldInfo, fields.Len())
|
|
for i := 0; i < fields.Len(); i++ {
|
|
fd := fields.Get(i)
|
|
|
|
fs := si.fieldsByNumber[fd.Number()]
|
|
isOneof := fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic()
|
|
if isOneof {
|
|
fs = si.oneofsByName[fd.ContainingOneof().Name()]
|
|
}
|
|
ft := fs.Type
|
|
var wiretag uint64
|
|
if !fd.IsPacked() {
|
|
wiretag = protowire.EncodeTag(fd.Number(), wireTypes[fd.Kind()])
|
|
} else {
|
|
wiretag = protowire.EncodeTag(fd.Number(), protowire.BytesType)
|
|
}
|
|
var fieldOffset offset
|
|
var funcs pointerCoderFuncs
|
|
var childMessage *MessageInfo
|
|
switch {
|
|
case ft == nil:
|
|
// This never occurs for generated message types.
|
|
// It implies that a hand-crafted type has missing Go fields
|
|
// for specific protobuf message fields.
|
|
funcs = pointerCoderFuncs{
|
|
size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
|
|
return 0
|
|
},
|
|
marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
|
return nil, nil
|
|
},
|
|
unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
|
|
panic("missing Go struct field for " + string(fd.FullName()))
|
|
},
|
|
isInit: func(p pointer, f *coderFieldInfo) error {
|
|
panic("missing Go struct field for " + string(fd.FullName()))
|
|
},
|
|
merge: func(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
|
|
panic("missing Go struct field for " + string(fd.FullName()))
|
|
},
|
|
}
|
|
case isOneof:
|
|
fieldOffset = offsetOf(fs, mi.Exporter)
|
|
case fd.IsWeak():
|
|
fieldOffset = si.weakOffset
|
|
funcs = makeWeakMessageFieldCoder(fd)
|
|
default:
|
|
fieldOffset = offsetOf(fs, mi.Exporter)
|
|
childMessage, funcs = fieldCoder(fd, ft)
|
|
}
|
|
cf := &preallocFields[i]
|
|
*cf = coderFieldInfo{
|
|
num: fd.Number(),
|
|
offset: fieldOffset,
|
|
wiretag: wiretag,
|
|
ft: ft,
|
|
tagsize: protowire.SizeVarint(wiretag),
|
|
funcs: funcs,
|
|
mi: childMessage,
|
|
validation: newFieldValidationInfo(mi, si, fd, ft),
|
|
isPointer: fd.Cardinality() == pref.Repeated || fd.HasPresence(),
|
|
isRequired: fd.Cardinality() == pref.Required,
|
|
}
|
|
mi.orderedCoderFields = append(mi.orderedCoderFields, cf)
|
|
mi.coderFields[cf.num] = cf
|
|
}
|
|
for i, oneofs := 0, mi.Desc.Oneofs(); i < oneofs.Len(); i++ {
|
|
if od := oneofs.Get(i); !od.IsSynthetic() {
|
|
mi.initOneofFieldCoders(od, si)
|
|
}
|
|
}
|
|
if messageset.IsMessageSet(mi.Desc) {
|
|
if !mi.extensionOffset.IsValid() {
|
|
panic(fmt.Sprintf("%v: MessageSet with no extensions field", mi.Desc.FullName()))
|
|
}
|
|
if !mi.unknownOffset.IsValid() {
|
|
panic(fmt.Sprintf("%v: MessageSet with no unknown field", mi.Desc.FullName()))
|
|
}
|
|
mi.isMessageSet = true
|
|
}
|
|
sort.Slice(mi.orderedCoderFields, func(i, j int) bool {
|
|
return mi.orderedCoderFields[i].num < mi.orderedCoderFields[j].num
|
|
})
|
|
|
|
var maxDense pref.FieldNumber
|
|
for _, cf := range mi.orderedCoderFields {
|
|
if cf.num >= 16 && cf.num >= 2*maxDense {
|
|
break
|
|
}
|
|
maxDense = cf.num
|
|
}
|
|
mi.denseCoderFields = make([]*coderFieldInfo, maxDense+1)
|
|
for _, cf := range mi.orderedCoderFields {
|
|
if int(cf.num) >= len(mi.denseCoderFields) {
|
|
break
|
|
}
|
|
mi.denseCoderFields[cf.num] = cf
|
|
}
|
|
|
|
// To preserve compatibility with historic wire output, marshal oneofs last.
|
|
if mi.Desc.Oneofs().Len() > 0 {
|
|
sort.Slice(mi.orderedCoderFields, func(i, j int) bool {
|
|
fi := fields.ByNumber(mi.orderedCoderFields[i].num)
|
|
fj := fields.ByNumber(mi.orderedCoderFields[j].num)
|
|
return order.LegacyFieldOrder(fi, fj)
|
|
})
|
|
}
|
|
|
|
mi.needsInitCheck = needsInitCheck(mi.Desc)
|
|
if mi.methods.Marshal == nil && mi.methods.Size == nil {
|
|
mi.methods.Flags |= piface.SupportMarshalDeterministic
|
|
mi.methods.Marshal = mi.marshal
|
|
mi.methods.Size = mi.size
|
|
}
|
|
if mi.methods.Unmarshal == nil {
|
|
mi.methods.Flags |= piface.SupportUnmarshalDiscardUnknown
|
|
mi.methods.Unmarshal = mi.unmarshal
|
|
}
|
|
if mi.methods.CheckInitialized == nil {
|
|
mi.methods.CheckInitialized = mi.checkInitialized
|
|
}
|
|
if mi.methods.Merge == nil {
|
|
mi.methods.Merge = mi.merge
|
|
}
|
|
}
|
|
|
|
// getUnknownBytes returns a *[]byte for the unknown fields.
|
|
// It is the caller's responsibility to check whether the pointer is nil.
|
|
// This function is specially designed to be inlineable.
|
|
func (mi *MessageInfo) getUnknownBytes(p pointer) *[]byte {
|
|
if mi.unknownPtrKind {
|
|
return *p.Apply(mi.unknownOffset).BytesPtr()
|
|
} else {
|
|
return p.Apply(mi.unknownOffset).Bytes()
|
|
}
|
|
}
|
|
|
|
// mutableUnknownBytes returns a *[]byte for the unknown fields.
|
|
// The returned pointer is guaranteed to not be nil.
|
|
func (mi *MessageInfo) mutableUnknownBytes(p pointer) *[]byte {
|
|
if mi.unknownPtrKind {
|
|
bp := p.Apply(mi.unknownOffset).BytesPtr()
|
|
if *bp == nil {
|
|
*bp = new([]byte)
|
|
}
|
|
return *bp
|
|
} else {
|
|
return p.Apply(mi.unknownOffset).Bytes()
|
|
}
|
|
}
|