mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 11:41:32 +01:00 
			
		
		
		
	* update github.com/blevesearch/bleve v2.0.2 -> v2.0.3 * github.com/denisenkom/go-mssqldb v0.9.0 -> v0.10.0 * github.com/editorconfig/editorconfig-core-go v2.4.1 -> v2.4.2 * github.com/go-chi/cors v1.1.1 -> v1.2.0 * github.com/go-git/go-billy v5.0.0 -> v5.1.0 * github.com/go-git/go-git v5.2.0 -> v5.3.0 * github.com/go-ldap/ldap v3.2.4 -> v3.3.0 * github.com/go-redis/redis v8.6.0 -> v8.8.2 * github.com/go-sql-driver/mysql v1.5.0 -> v1.6.0 * github.com/go-swagger/go-swagger v0.26.1 -> v0.27.0 * github.com/lib/pq v1.9.0 -> v1.10.1 * github.com/mattn/go-sqlite3 v1.14.6 -> v1.14.7 * github.com/go-testfixtures/testfixtures v3.5.0 -> v3.6.0 * github.com/issue9/identicon v1.0.1 -> v1.2.0 * github.com/klauspost/compress v1.11.8 -> v1.12.1 * github.com/mgechev/revive v1.0.3 -> v1.0.6 * github.com/microcosm-cc/bluemonday v1.0.7 -> v1.0.8 * github.com/niklasfasching/go-org v1.4.0 -> v1.5.0 * github.com/olivere/elastic v7.0.22 -> v7.0.24 * github.com/pelletier/go-toml v1.8.1 -> v1.9.0 * github.com/prometheus/client_golang v1.9.0 -> v1.10.0 * github.com/xanzy/go-gitlab v0.44.0 -> v0.48.0 * github.com/yuin/goldmark v1.3.3 -> v1.3.5 * github.com/6543/go-version v1.2.4 -> v1.3.1 * do github.com/lib/pq v1.10.0 -> v1.10.1 again ...
		
			
				
	
	
		
			277 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
			
		
		
	
	
			277 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
| // Copyright 2018 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"
 | |
| 	"strconv"
 | |
| 	"strings"
 | |
| 	"sync"
 | |
| 	"sync/atomic"
 | |
| 
 | |
| 	"google.golang.org/protobuf/internal/genid"
 | |
| 	"google.golang.org/protobuf/reflect/protoreflect"
 | |
| 	pref "google.golang.org/protobuf/reflect/protoreflect"
 | |
| 	preg "google.golang.org/protobuf/reflect/protoregistry"
 | |
| )
 | |
| 
 | |
| // MessageInfo provides protobuf related functionality for a given Go type
 | |
| // that represents a message. A given instance of MessageInfo is tied to
 | |
| // exactly one Go type, which must be a pointer to a struct type.
 | |
| //
 | |
| // The exported fields must be populated before any methods are called
 | |
| // and cannot be mutated after set.
 | |
| type MessageInfo struct {
 | |
| 	// GoReflectType is the underlying message Go type and must be populated.
 | |
| 	GoReflectType reflect.Type // pointer to struct
 | |
| 
 | |
| 	// Desc is the underlying message descriptor type and must be populated.
 | |
| 	Desc pref.MessageDescriptor
 | |
| 
 | |
| 	// Exporter must be provided in a purego environment in order to provide
 | |
| 	// access to unexported fields.
 | |
| 	Exporter exporter
 | |
| 
 | |
| 	// OneofWrappers is list of pointers to oneof wrapper struct types.
 | |
| 	OneofWrappers []interface{}
 | |
| 
 | |
| 	initMu   sync.Mutex // protects all unexported fields
 | |
| 	initDone uint32
 | |
| 
 | |
| 	reflectMessageInfo // for reflection implementation
 | |
| 	coderMessageInfo   // for fast-path method implementations
 | |
| }
 | |
| 
 | |
| // exporter is a function that returns a reference to the ith field of v,
 | |
| // where v is a pointer to a struct. It returns nil if it does not support
 | |
| // exporting the requested field (e.g., already exported).
 | |
| type exporter func(v interface{}, i int) interface{}
 | |
| 
 | |
| // getMessageInfo returns the MessageInfo for any message type that
 | |
| // is generated by our implementation of protoc-gen-go (for v2 and on).
 | |
| // If it is unable to obtain a MessageInfo, it returns nil.
 | |
| func getMessageInfo(mt reflect.Type) *MessageInfo {
 | |
| 	m, ok := reflect.Zero(mt).Interface().(pref.ProtoMessage)
 | |
| 	if !ok {
 | |
| 		return nil
 | |
| 	}
 | |
| 	mr, ok := m.ProtoReflect().(interface{ ProtoMessageInfo() *MessageInfo })
 | |
| 	if !ok {
 | |
| 		return nil
 | |
| 	}
 | |
| 	return mr.ProtoMessageInfo()
 | |
| }
 | |
| 
 | |
| func (mi *MessageInfo) init() {
 | |
| 	// This function is called in the hot path. Inline the sync.Once logic,
 | |
| 	// since allocating a closure for Once.Do is expensive.
 | |
| 	// Keep init small to ensure that it can be inlined.
 | |
| 	if atomic.LoadUint32(&mi.initDone) == 0 {
 | |
| 		mi.initOnce()
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (mi *MessageInfo) initOnce() {
 | |
| 	mi.initMu.Lock()
 | |
| 	defer mi.initMu.Unlock()
 | |
| 	if mi.initDone == 1 {
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	t := mi.GoReflectType
 | |
| 	if t.Kind() != reflect.Ptr && t.Elem().Kind() != reflect.Struct {
 | |
| 		panic(fmt.Sprintf("got %v, want *struct kind", t))
 | |
| 	}
 | |
| 	t = t.Elem()
 | |
| 
 | |
| 	si := mi.makeStructInfo(t)
 | |
| 	mi.makeReflectFuncs(t, si)
 | |
| 	mi.makeCoderMethods(t, si)
 | |
| 
 | |
| 	atomic.StoreUint32(&mi.initDone, 1)
 | |
| }
 | |
| 
 | |
| // getPointer returns the pointer for a message, which should be of
 | |
| // the type of the MessageInfo. If the message is of a different type,
 | |
| // it returns ok==false.
 | |
| func (mi *MessageInfo) getPointer(m pref.Message) (p pointer, ok bool) {
 | |
| 	switch m := m.(type) {
 | |
| 	case *messageState:
 | |
| 		return m.pointer(), m.messageInfo() == mi
 | |
| 	case *messageReflectWrapper:
 | |
| 		return m.pointer(), m.messageInfo() == mi
 | |
| 	}
 | |
| 	return pointer{}, false
 | |
| }
 | |
| 
 | |
| type (
 | |
| 	SizeCache       = int32
 | |
| 	WeakFields      = map[int32]protoreflect.ProtoMessage
 | |
| 	UnknownFields   = unknownFieldsA // TODO: switch to unknownFieldsB
 | |
| 	unknownFieldsA  = []byte
 | |
| 	unknownFieldsB  = *[]byte
 | |
| 	ExtensionFields = map[int32]ExtensionField
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	sizecacheType       = reflect.TypeOf(SizeCache(0))
 | |
| 	weakFieldsType      = reflect.TypeOf(WeakFields(nil))
 | |
| 	unknownFieldsAType  = reflect.TypeOf(unknownFieldsA(nil))
 | |
| 	unknownFieldsBType  = reflect.TypeOf(unknownFieldsB(nil))
 | |
| 	extensionFieldsType = reflect.TypeOf(ExtensionFields(nil))
 | |
| )
 | |
| 
 | |
| type structInfo struct {
 | |
| 	sizecacheOffset offset
 | |
| 	sizecacheType   reflect.Type
 | |
| 	weakOffset      offset
 | |
| 	weakType        reflect.Type
 | |
| 	unknownOffset   offset
 | |
| 	unknownType     reflect.Type
 | |
| 	extensionOffset offset
 | |
| 	extensionType   reflect.Type
 | |
| 
 | |
| 	fieldsByNumber        map[pref.FieldNumber]reflect.StructField
 | |
| 	oneofsByName          map[pref.Name]reflect.StructField
 | |
| 	oneofWrappersByType   map[reflect.Type]pref.FieldNumber
 | |
| 	oneofWrappersByNumber map[pref.FieldNumber]reflect.Type
 | |
| }
 | |
| 
 | |
| func (mi *MessageInfo) makeStructInfo(t reflect.Type) structInfo {
 | |
| 	si := structInfo{
 | |
| 		sizecacheOffset: invalidOffset,
 | |
| 		weakOffset:      invalidOffset,
 | |
| 		unknownOffset:   invalidOffset,
 | |
| 		extensionOffset: invalidOffset,
 | |
| 
 | |
| 		fieldsByNumber:        map[pref.FieldNumber]reflect.StructField{},
 | |
| 		oneofsByName:          map[pref.Name]reflect.StructField{},
 | |
| 		oneofWrappersByType:   map[reflect.Type]pref.FieldNumber{},
 | |
| 		oneofWrappersByNumber: map[pref.FieldNumber]reflect.Type{},
 | |
| 	}
 | |
| 
 | |
| fieldLoop:
 | |
| 	for i := 0; i < t.NumField(); i++ {
 | |
| 		switch f := t.Field(i); f.Name {
 | |
| 		case genid.SizeCache_goname, genid.SizeCacheA_goname:
 | |
| 			if f.Type == sizecacheType {
 | |
| 				si.sizecacheOffset = offsetOf(f, mi.Exporter)
 | |
| 				si.sizecacheType = f.Type
 | |
| 			}
 | |
| 		case genid.WeakFields_goname, genid.WeakFieldsA_goname:
 | |
| 			if f.Type == weakFieldsType {
 | |
| 				si.weakOffset = offsetOf(f, mi.Exporter)
 | |
| 				si.weakType = f.Type
 | |
| 			}
 | |
| 		case genid.UnknownFields_goname, genid.UnknownFieldsA_goname:
 | |
| 			if f.Type == unknownFieldsAType || f.Type == unknownFieldsBType {
 | |
| 				si.unknownOffset = offsetOf(f, mi.Exporter)
 | |
| 				si.unknownType = f.Type
 | |
| 			}
 | |
| 		case genid.ExtensionFields_goname, genid.ExtensionFieldsA_goname, genid.ExtensionFieldsB_goname:
 | |
| 			if f.Type == extensionFieldsType {
 | |
| 				si.extensionOffset = offsetOf(f, mi.Exporter)
 | |
| 				si.extensionType = f.Type
 | |
| 			}
 | |
| 		default:
 | |
| 			for _, s := range strings.Split(f.Tag.Get("protobuf"), ",") {
 | |
| 				if len(s) > 0 && strings.Trim(s, "0123456789") == "" {
 | |
| 					n, _ := strconv.ParseUint(s, 10, 64)
 | |
| 					si.fieldsByNumber[pref.FieldNumber(n)] = f
 | |
| 					continue fieldLoop
 | |
| 				}
 | |
| 			}
 | |
| 			if s := f.Tag.Get("protobuf_oneof"); len(s) > 0 {
 | |
| 				si.oneofsByName[pref.Name(s)] = f
 | |
| 				continue fieldLoop
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// Derive a mapping of oneof wrappers to fields.
 | |
| 	oneofWrappers := mi.OneofWrappers
 | |
| 	for _, method := range []string{"XXX_OneofFuncs", "XXX_OneofWrappers"} {
 | |
| 		if fn, ok := reflect.PtrTo(t).MethodByName(method); ok {
 | |
| 			for _, v := range fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))}) {
 | |
| 				if vs, ok := v.Interface().([]interface{}); ok {
 | |
| 					oneofWrappers = vs
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	for _, v := range oneofWrappers {
 | |
| 		tf := reflect.TypeOf(v).Elem()
 | |
| 		f := tf.Field(0)
 | |
| 		for _, s := range strings.Split(f.Tag.Get("protobuf"), ",") {
 | |
| 			if len(s) > 0 && strings.Trim(s, "0123456789") == "" {
 | |
| 				n, _ := strconv.ParseUint(s, 10, 64)
 | |
| 				si.oneofWrappersByType[tf] = pref.FieldNumber(n)
 | |
| 				si.oneofWrappersByNumber[pref.FieldNumber(n)] = tf
 | |
| 				break
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return si
 | |
| }
 | |
| 
 | |
| func (mi *MessageInfo) New() protoreflect.Message {
 | |
| 	return mi.MessageOf(reflect.New(mi.GoReflectType.Elem()).Interface())
 | |
| }
 | |
| func (mi *MessageInfo) Zero() protoreflect.Message {
 | |
| 	return mi.MessageOf(reflect.Zero(mi.GoReflectType).Interface())
 | |
| }
 | |
| func (mi *MessageInfo) Descriptor() protoreflect.MessageDescriptor {
 | |
| 	return mi.Desc
 | |
| }
 | |
| func (mi *MessageInfo) Enum(i int) protoreflect.EnumType {
 | |
| 	mi.init()
 | |
| 	fd := mi.Desc.Fields().Get(i)
 | |
| 	return Export{}.EnumTypeOf(mi.fieldTypes[fd.Number()])
 | |
| }
 | |
| func (mi *MessageInfo) Message(i int) protoreflect.MessageType {
 | |
| 	mi.init()
 | |
| 	fd := mi.Desc.Fields().Get(i)
 | |
| 	switch {
 | |
| 	case fd.IsWeak():
 | |
| 		mt, _ := preg.GlobalTypes.FindMessageByName(fd.Message().FullName())
 | |
| 		return mt
 | |
| 	case fd.IsMap():
 | |
| 		return mapEntryType{fd.Message(), mi.fieldTypes[fd.Number()]}
 | |
| 	default:
 | |
| 		return Export{}.MessageTypeOf(mi.fieldTypes[fd.Number()])
 | |
| 	}
 | |
| }
 | |
| 
 | |
| type mapEntryType struct {
 | |
| 	desc    protoreflect.MessageDescriptor
 | |
| 	valType interface{} // zero value of enum or message type
 | |
| }
 | |
| 
 | |
| func (mt mapEntryType) New() protoreflect.Message {
 | |
| 	return nil
 | |
| }
 | |
| func (mt mapEntryType) Zero() protoreflect.Message {
 | |
| 	return nil
 | |
| }
 | |
| func (mt mapEntryType) Descriptor() protoreflect.MessageDescriptor {
 | |
| 	return mt.desc
 | |
| }
 | |
| func (mt mapEntryType) Enum(i int) protoreflect.EnumType {
 | |
| 	fd := mt.desc.Fields().Get(i)
 | |
| 	if fd.Enum() == nil {
 | |
| 		return nil
 | |
| 	}
 | |
| 	return Export{}.EnumTypeOf(mt.valType)
 | |
| }
 | |
| func (mt mapEntryType) Message(i int) protoreflect.MessageType {
 | |
| 	fd := mt.desc.Fields().Get(i)
 | |
| 	if fd.Message() == nil {
 | |
| 		return nil
 | |
| 	}
 | |
| 	return Export{}.MessageTypeOf(mt.valType)
 | |
| }
 |