1
0
Fork 0
forked from forgejo/forgejo

Vendor Update: go-gitlab v0.22.1 -> v0.31.0 (#11136)

* vendor update: go-gitlab to v0.31.0

* migrate client init to v0.31.0

* refactor
This commit is contained in:
6543 2020-04-19 22:23:05 +02:00 committed by GitHub
parent 5c092eb0ef
commit 82dbb34c9c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
256 changed files with 36039 additions and 12965 deletions

View file

@ -0,0 +1,155 @@
// 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 filedesc provides functionality for constructing descriptors.
package filedesc
import (
"google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/internal/fieldnum"
"google.golang.org/protobuf/reflect/protoreflect"
pref "google.golang.org/protobuf/reflect/protoreflect"
preg "google.golang.org/protobuf/reflect/protoregistry"
)
// Builder construct a protoreflect.FileDescriptor from the raw descriptor.
type Builder struct {
// GoPackagePath is the Go package path that is invoking this builder.
GoPackagePath string
// RawDescriptor is the wire-encoded bytes of FileDescriptorProto
// and must be populated.
RawDescriptor []byte
// NumEnums is the total number of enums declared in the file.
NumEnums int32
// NumMessages is the total number of messages declared in the file.
// It includes the implicit message declarations for map entries.
NumMessages int32
// NumExtensions is the total number of extensions declared in the file.
NumExtensions int32
// NumServices is the total number of services declared in the file.
NumServices int32
// TypeResolver resolves extension field types for descriptor options.
// If nil, it uses protoregistry.GlobalTypes.
TypeResolver interface {
preg.ExtensionTypeResolver
}
// FileRegistry is use to lookup file, enum, and message dependencies.
// Once constructed, the file descriptor is registered here.
// If nil, it uses protoregistry.GlobalFiles.
FileRegistry interface {
FindFileByPath(string) (protoreflect.FileDescriptor, error)
FindDescriptorByName(pref.FullName) (pref.Descriptor, error)
RegisterFile(pref.FileDescriptor) error
}
}
// resolverByIndex is an interface Builder.FileRegistry may implement.
// If so, it permits looking up an enum or message dependency based on the
// sub-list and element index into filetype.Builder.DependencyIndexes.
type resolverByIndex interface {
FindEnumByIndex(int32, int32, []Enum, []Message) pref.EnumDescriptor
FindMessageByIndex(int32, int32, []Enum, []Message) pref.MessageDescriptor
}
// Indexes of each sub-list in filetype.Builder.DependencyIndexes.
const (
listFieldDeps int32 = iota
listExtTargets
listExtDeps
listMethInDeps
listMethOutDeps
)
// Out is the output of the Builder.
type Out struct {
File pref.FileDescriptor
// Enums is all enum descriptors in "flattened ordering".
Enums []Enum
// Messages is all message descriptors in "flattened ordering".
// It includes the implicit message declarations for map entries.
Messages []Message
// Extensions is all extension descriptors in "flattened ordering".
Extensions []Extension
// Service is all service descriptors in "flattened ordering".
Services []Service
}
// Build constructs a FileDescriptor given the parameters set in Builder.
// It assumes that the inputs are well-formed and panics if any inconsistencies
// are encountered.
//
// If NumEnums+NumMessages+NumExtensions+NumServices is zero,
// then Build automatically derives them from the raw descriptor.
func (db Builder) Build() (out Out) {
// Populate the counts if uninitialized.
if db.NumEnums+db.NumMessages+db.NumExtensions+db.NumServices == 0 {
db.unmarshalCounts(db.RawDescriptor, true)
}
// Initialize resolvers and registries if unpopulated.
if db.TypeResolver == nil {
db.TypeResolver = preg.GlobalTypes
}
if db.FileRegistry == nil {
db.FileRegistry = preg.GlobalFiles
}
fd := newRawFile(db)
out.File = fd
out.Enums = fd.allEnums
out.Messages = fd.allMessages
out.Extensions = fd.allExtensions
out.Services = fd.allServices
if err := db.FileRegistry.RegisterFile(fd); err != nil {
panic(err)
}
return out
}
// unmarshalCounts counts the number of enum, message, extension, and service
// declarations in the raw message, which is either a FileDescriptorProto
// or a MessageDescriptorProto depending on whether isFile is set.
func (db *Builder) unmarshalCounts(b []byte, isFile bool) {
for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b)
b = b[n:]
switch typ {
case protowire.BytesType:
v, m := protowire.ConsumeBytes(b)
b = b[m:]
if isFile {
switch num {
case fieldnum.FileDescriptorProto_EnumType:
db.NumEnums++
case fieldnum.FileDescriptorProto_MessageType:
db.unmarshalCounts(v, false)
db.NumMessages++
case fieldnum.FileDescriptorProto_Extension:
db.NumExtensions++
case fieldnum.FileDescriptorProto_Service:
db.NumServices++
}
} else {
switch num {
case fieldnum.DescriptorProto_EnumType:
db.NumEnums++
case fieldnum.DescriptorProto_NestedType:
db.unmarshalCounts(v, false)
db.NumMessages++
case fieldnum.DescriptorProto_Extension:
db.NumExtensions++
}
}
default:
m := protowire.ConsumeFieldValue(num, typ, b)
b = b[m:]
}
}
}

View file

@ -0,0 +1,598 @@
// 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 filedesc
import (
"bytes"
"fmt"
"sync"
"sync/atomic"
"google.golang.org/protobuf/internal/descfmt"
"google.golang.org/protobuf/internal/descopts"
"google.golang.org/protobuf/internal/encoding/defval"
"google.golang.org/protobuf/internal/pragma"
"google.golang.org/protobuf/internal/strs"
pref "google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry"
)
// The types in this file may have a suffix:
// • L0: Contains fields common to all descriptors (except File) and
// must be initialized up front.
// • L1: Contains fields specific to a descriptor and
// must be initialized up front.
// • L2: Contains fields that are lazily initialized when constructing
// from the raw file descriptor. When constructing as a literal, the L2
// fields must be initialized up front.
//
// The types are exported so that packages like reflect/protodesc can
// directly construct descriptors.
type (
File struct {
fileRaw
L1 FileL1
once uint32 // atomically set if L2 is valid
mu sync.Mutex // protects L2
L2 *FileL2
}
FileL1 struct {
Syntax pref.Syntax
Path string
Package pref.FullName
Enums Enums
Messages Messages
Extensions Extensions
Services Services
}
FileL2 struct {
Options func() pref.ProtoMessage
Imports FileImports
Locations SourceLocations
}
)
func (fd *File) ParentFile() pref.FileDescriptor { return fd }
func (fd *File) Parent() pref.Descriptor { return nil }
func (fd *File) Index() int { return 0 }
func (fd *File) Syntax() pref.Syntax { return fd.L1.Syntax }
func (fd *File) Name() pref.Name { return fd.L1.Package.Name() }
func (fd *File) FullName() pref.FullName { return fd.L1.Package }
func (fd *File) IsPlaceholder() bool { return false }
func (fd *File) Options() pref.ProtoMessage {
if f := fd.lazyInit().Options; f != nil {
return f()
}
return descopts.File
}
func (fd *File) Path() string { return fd.L1.Path }
func (fd *File) Package() pref.FullName { return fd.L1.Package }
func (fd *File) Imports() pref.FileImports { return &fd.lazyInit().Imports }
func (fd *File) Enums() pref.EnumDescriptors { return &fd.L1.Enums }
func (fd *File) Messages() pref.MessageDescriptors { return &fd.L1.Messages }
func (fd *File) Extensions() pref.ExtensionDescriptors { return &fd.L1.Extensions }
func (fd *File) Services() pref.ServiceDescriptors { return &fd.L1.Services }
func (fd *File) SourceLocations() pref.SourceLocations { return &fd.L2.Locations }
func (fd *File) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, fd) }
func (fd *File) ProtoType(pref.FileDescriptor) {}
func (fd *File) ProtoInternal(pragma.DoNotImplement) {}
func (fd *File) lazyInit() *FileL2 {
if atomic.LoadUint32(&fd.once) == 0 {
fd.lazyInitOnce()
}
return fd.L2
}
func (fd *File) lazyInitOnce() {
fd.mu.Lock()
if fd.L2 == nil {
fd.lazyRawInit() // recursively initializes all L2 structures
}
atomic.StoreUint32(&fd.once, 1)
fd.mu.Unlock()
}
// ProtoLegacyRawDesc is a pseudo-internal API for allowing the v1 code
// to be able to retrieve the raw descriptor.
//
// WARNING: This method is exempt from the compatibility promise and may be
// removed in the future without warning.
func (fd *File) ProtoLegacyRawDesc() []byte {
return fd.builder.RawDescriptor
}
// GoPackagePath is a pseudo-internal API for determining the Go package path
// that this file descriptor is declared in.
//
// WARNING: This method is exempt from the compatibility promise and may be
// removed in the future without warning.
func (fd *File) GoPackagePath() string {
return fd.builder.GoPackagePath
}
type (
Enum struct {
Base
L1 EnumL1
L2 *EnumL2 // protected by fileDesc.once
}
EnumL1 struct {
eagerValues bool // controls whether EnumL2.Values is already populated
}
EnumL2 struct {
Options func() pref.ProtoMessage
Values EnumValues
ReservedNames Names
ReservedRanges EnumRanges
}
EnumValue struct {
Base
L1 EnumValueL1
}
EnumValueL1 struct {
Options func() pref.ProtoMessage
Number pref.EnumNumber
}
)
func (ed *Enum) Options() pref.ProtoMessage {
if f := ed.lazyInit().Options; f != nil {
return f()
}
return descopts.Enum
}
func (ed *Enum) Values() pref.EnumValueDescriptors {
if ed.L1.eagerValues {
return &ed.L2.Values
}
return &ed.lazyInit().Values
}
func (ed *Enum) ReservedNames() pref.Names { return &ed.lazyInit().ReservedNames }
func (ed *Enum) ReservedRanges() pref.EnumRanges { return &ed.lazyInit().ReservedRanges }
func (ed *Enum) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, ed) }
func (ed *Enum) ProtoType(pref.EnumDescriptor) {}
func (ed *Enum) lazyInit() *EnumL2 {
ed.L0.ParentFile.lazyInit() // implicitly initializes L2
return ed.L2
}
func (ed *EnumValue) Options() pref.ProtoMessage {
if f := ed.L1.Options; f != nil {
return f()
}
return descopts.EnumValue
}
func (ed *EnumValue) Number() pref.EnumNumber { return ed.L1.Number }
func (ed *EnumValue) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, ed) }
func (ed *EnumValue) ProtoType(pref.EnumValueDescriptor) {}
type (
Message struct {
Base
L1 MessageL1
L2 *MessageL2 // protected by fileDesc.once
}
MessageL1 struct {
Enums Enums
Messages Messages
Extensions Extensions
IsMapEntry bool // promoted from google.protobuf.MessageOptions
IsMessageSet bool // promoted from google.protobuf.MessageOptions
}
MessageL2 struct {
Options func() pref.ProtoMessage
Fields Fields
Oneofs Oneofs
ReservedNames Names
ReservedRanges FieldRanges
RequiredNumbers FieldNumbers // must be consistent with Fields.Cardinality
ExtensionRanges FieldRanges
ExtensionRangeOptions []func() pref.ProtoMessage // must be same length as ExtensionRanges
}
Field struct {
Base
L1 FieldL1
}
FieldL1 struct {
Options func() pref.ProtoMessage
Number pref.FieldNumber
Cardinality pref.Cardinality // must be consistent with Message.RequiredNumbers
Kind pref.Kind
JSONName jsonName
IsWeak bool // promoted from google.protobuf.FieldOptions
HasPacked bool // promoted from google.protobuf.FieldOptions
IsPacked bool // promoted from google.protobuf.FieldOptions
HasEnforceUTF8 bool // promoted from google.protobuf.FieldOptions
EnforceUTF8 bool // promoted from google.protobuf.FieldOptions
Default defaultValue
ContainingOneof pref.OneofDescriptor // must be consistent with Message.Oneofs.Fields
Enum pref.EnumDescriptor
Message pref.MessageDescriptor
}
Oneof struct {
Base
L1 OneofL1
}
OneofL1 struct {
Options func() pref.ProtoMessage
Fields OneofFields // must be consistent with Message.Fields.ContainingOneof
}
)
func (md *Message) Options() pref.ProtoMessage {
if f := md.lazyInit().Options; f != nil {
return f()
}
return descopts.Message
}
func (md *Message) IsMapEntry() bool { return md.L1.IsMapEntry }
func (md *Message) Fields() pref.FieldDescriptors { return &md.lazyInit().Fields }
func (md *Message) Oneofs() pref.OneofDescriptors { return &md.lazyInit().Oneofs }
func (md *Message) ReservedNames() pref.Names { return &md.lazyInit().ReservedNames }
func (md *Message) ReservedRanges() pref.FieldRanges { return &md.lazyInit().ReservedRanges }
func (md *Message) RequiredNumbers() pref.FieldNumbers { return &md.lazyInit().RequiredNumbers }
func (md *Message) ExtensionRanges() pref.FieldRanges { return &md.lazyInit().ExtensionRanges }
func (md *Message) ExtensionRangeOptions(i int) pref.ProtoMessage {
if f := md.lazyInit().ExtensionRangeOptions[i]; f != nil {
return f()
}
return descopts.ExtensionRange
}
func (md *Message) Enums() pref.EnumDescriptors { return &md.L1.Enums }
func (md *Message) Messages() pref.MessageDescriptors { return &md.L1.Messages }
func (md *Message) Extensions() pref.ExtensionDescriptors { return &md.L1.Extensions }
func (md *Message) ProtoType(pref.MessageDescriptor) {}
func (md *Message) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, md) }
func (md *Message) lazyInit() *MessageL2 {
md.L0.ParentFile.lazyInit() // implicitly initializes L2
return md.L2
}
// IsMessageSet is a pseudo-internal API for checking whether a message
// should serialize in the proto1 message format.
//
// WARNING: This method is exempt from the compatibility promise and may be
// removed in the future without warning.
func (md *Message) IsMessageSet() bool {
return md.L1.IsMessageSet
}
func (fd *Field) Options() pref.ProtoMessage {
if f := fd.L1.Options; f != nil {
return f()
}
return descopts.Field
}
func (fd *Field) Number() pref.FieldNumber { return fd.L1.Number }
func (fd *Field) Cardinality() pref.Cardinality { return fd.L1.Cardinality }
func (fd *Field) Kind() pref.Kind { return fd.L1.Kind }
func (fd *Field) HasJSONName() bool { return fd.L1.JSONName.has }
func (fd *Field) JSONName() string { return fd.L1.JSONName.get(fd) }
func (fd *Field) IsPacked() bool {
if !fd.L1.HasPacked && fd.L0.ParentFile.L1.Syntax != pref.Proto2 && fd.L1.Cardinality == pref.Repeated {
switch fd.L1.Kind {
case pref.StringKind, pref.BytesKind, pref.MessageKind, pref.GroupKind:
default:
return true
}
}
return fd.L1.IsPacked
}
func (fd *Field) IsExtension() bool { return false }
func (fd *Field) IsWeak() bool { return fd.L1.IsWeak }
func (fd *Field) IsList() bool { return fd.Cardinality() == pref.Repeated && !fd.IsMap() }
func (fd *Field) IsMap() bool { return fd.Message() != nil && fd.Message().IsMapEntry() }
func (fd *Field) MapKey() pref.FieldDescriptor {
if !fd.IsMap() {
return nil
}
return fd.Message().Fields().ByNumber(1)
}
func (fd *Field) MapValue() pref.FieldDescriptor {
if !fd.IsMap() {
return nil
}
return fd.Message().Fields().ByNumber(2)
}
func (fd *Field) HasDefault() bool { return fd.L1.Default.has }
func (fd *Field) Default() pref.Value { return fd.L1.Default.get(fd) }
func (fd *Field) DefaultEnumValue() pref.EnumValueDescriptor { return fd.L1.Default.enum }
func (fd *Field) ContainingOneof() pref.OneofDescriptor { return fd.L1.ContainingOneof }
func (fd *Field) ContainingMessage() pref.MessageDescriptor {
return fd.L0.Parent.(pref.MessageDescriptor)
}
func (fd *Field) Enum() pref.EnumDescriptor {
return fd.L1.Enum
}
func (fd *Field) Message() pref.MessageDescriptor {
if fd.L1.IsWeak {
if d, _ := protoregistry.GlobalFiles.FindDescriptorByName(fd.L1.Message.FullName()); d != nil {
return d.(pref.MessageDescriptor)
}
}
return fd.L1.Message
}
func (fd *Field) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, fd) }
func (fd *Field) ProtoType(pref.FieldDescriptor) {}
// EnforceUTF8 is a pseudo-internal API to determine whether to enforce UTF-8
// validation for the string field. This exists for Google-internal use only
// since proto3 did not enforce UTF-8 validity prior to the open-source release.
// If this method does not exist, the default is to enforce valid UTF-8.
//
// WARNING: This method is exempt from the compatibility promise and may be
// removed in the future without warning.
func (fd *Field) EnforceUTF8() bool {
if fd.L1.HasEnforceUTF8 {
return fd.L1.EnforceUTF8
}
return fd.L0.ParentFile.L1.Syntax == pref.Proto3
}
func (od *Oneof) Options() pref.ProtoMessage {
if f := od.L1.Options; f != nil {
return f()
}
return descopts.Oneof
}
func (od *Oneof) Fields() pref.FieldDescriptors { return &od.L1.Fields }
func (od *Oneof) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, od) }
func (od *Oneof) ProtoType(pref.OneofDescriptor) {}
type (
Extension struct {
Base
L1 ExtensionL1
L2 *ExtensionL2 // protected by fileDesc.once
}
ExtensionL1 struct {
Number pref.FieldNumber
Extendee pref.MessageDescriptor
Cardinality pref.Cardinality
Kind pref.Kind
}
ExtensionL2 struct {
Options func() pref.ProtoMessage
JSONName jsonName
IsPacked bool // promoted from google.protobuf.FieldOptions
Default defaultValue
Enum pref.EnumDescriptor
Message pref.MessageDescriptor
}
)
func (xd *Extension) Options() pref.ProtoMessage {
if f := xd.lazyInit().Options; f != nil {
return f()
}
return descopts.Field
}
func (xd *Extension) Number() pref.FieldNumber { return xd.L1.Number }
func (xd *Extension) Cardinality() pref.Cardinality { return xd.L1.Cardinality }
func (xd *Extension) Kind() pref.Kind { return xd.L1.Kind }
func (xd *Extension) HasJSONName() bool { return xd.lazyInit().JSONName.has }
func (xd *Extension) JSONName() string { return xd.lazyInit().JSONName.get(xd) }
func (xd *Extension) IsPacked() bool { return xd.lazyInit().IsPacked }
func (xd *Extension) IsExtension() bool { return true }
func (xd *Extension) IsWeak() bool { return false }
func (xd *Extension) IsList() bool { return xd.Cardinality() == pref.Repeated }
func (xd *Extension) IsMap() bool { return false }
func (xd *Extension) MapKey() pref.FieldDescriptor { return nil }
func (xd *Extension) MapValue() pref.FieldDescriptor { return nil }
func (xd *Extension) HasDefault() bool { return xd.lazyInit().Default.has }
func (xd *Extension) Default() pref.Value { return xd.lazyInit().Default.get(xd) }
func (xd *Extension) DefaultEnumValue() pref.EnumValueDescriptor { return xd.lazyInit().Default.enum }
func (xd *Extension) ContainingOneof() pref.OneofDescriptor { return nil }
func (xd *Extension) ContainingMessage() pref.MessageDescriptor { return xd.L1.Extendee }
func (xd *Extension) Enum() pref.EnumDescriptor { return xd.lazyInit().Enum }
func (xd *Extension) Message() pref.MessageDescriptor { return xd.lazyInit().Message }
func (xd *Extension) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, xd) }
func (xd *Extension) ProtoType(pref.FieldDescriptor) {}
func (xd *Extension) ProtoInternal(pragma.DoNotImplement) {}
func (xd *Extension) lazyInit() *ExtensionL2 {
xd.L0.ParentFile.lazyInit() // implicitly initializes L2
return xd.L2
}
type (
Service struct {
Base
L1 ServiceL1
L2 *ServiceL2 // protected by fileDesc.once
}
ServiceL1 struct{}
ServiceL2 struct {
Options func() pref.ProtoMessage
Methods Methods
}
Method struct {
Base
L1 MethodL1
}
MethodL1 struct {
Options func() pref.ProtoMessage
Input pref.MessageDescriptor
Output pref.MessageDescriptor
IsStreamingClient bool
IsStreamingServer bool
}
)
func (sd *Service) Options() pref.ProtoMessage {
if f := sd.lazyInit().Options; f != nil {
return f()
}
return descopts.Service
}
func (sd *Service) Methods() pref.MethodDescriptors { return &sd.lazyInit().Methods }
func (sd *Service) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, sd) }
func (sd *Service) ProtoType(pref.ServiceDescriptor) {}
func (sd *Service) ProtoInternal(pragma.DoNotImplement) {}
func (sd *Service) lazyInit() *ServiceL2 {
sd.L0.ParentFile.lazyInit() // implicitly initializes L2
return sd.L2
}
func (md *Method) Options() pref.ProtoMessage {
if f := md.L1.Options; f != nil {
return f()
}
return descopts.Method
}
func (md *Method) Input() pref.MessageDescriptor { return md.L1.Input }
func (md *Method) Output() pref.MessageDescriptor { return md.L1.Output }
func (md *Method) IsStreamingClient() bool { return md.L1.IsStreamingClient }
func (md *Method) IsStreamingServer() bool { return md.L1.IsStreamingServer }
func (md *Method) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, md) }
func (md *Method) ProtoType(pref.MethodDescriptor) {}
func (md *Method) ProtoInternal(pragma.DoNotImplement) {}
// Surrogate files are can be used to create standalone descriptors
// where the syntax is only information derived from the parent file.
var (
SurrogateProto2 = &File{L1: FileL1{Syntax: pref.Proto2}, L2: &FileL2{}}
SurrogateProto3 = &File{L1: FileL1{Syntax: pref.Proto3}, L2: &FileL2{}}
)
type (
Base struct {
L0 BaseL0
}
BaseL0 struct {
FullName pref.FullName // must be populated
ParentFile *File // must be populated
Parent pref.Descriptor
Index int
}
)
func (d *Base) Name() pref.Name { return d.L0.FullName.Name() }
func (d *Base) FullName() pref.FullName { return d.L0.FullName }
func (d *Base) ParentFile() pref.FileDescriptor {
if d.L0.ParentFile == SurrogateProto2 || d.L0.ParentFile == SurrogateProto3 {
return nil // surrogate files are not real parents
}
return d.L0.ParentFile
}
func (d *Base) Parent() pref.Descriptor { return d.L0.Parent }
func (d *Base) Index() int { return d.L0.Index }
func (d *Base) Syntax() pref.Syntax { return d.L0.ParentFile.Syntax() }
func (d *Base) IsPlaceholder() bool { return false }
func (d *Base) ProtoInternal(pragma.DoNotImplement) {}
type jsonName struct {
has bool
once sync.Once
name string
}
// Init initializes the name. It is exported for use by other internal packages.
func (js *jsonName) Init(s string) {
js.has = true
js.name = s
}
func (js *jsonName) get(fd pref.FieldDescriptor) string {
if !js.has {
js.once.Do(func() {
js.name = strs.JSONCamelCase(string(fd.Name()))
})
}
return js.name
}
func DefaultValue(v pref.Value, ev pref.EnumValueDescriptor) defaultValue {
dv := defaultValue{has: v.IsValid(), val: v, enum: ev}
if b, ok := v.Interface().([]byte); ok {
// Store a copy of the default bytes, so that we can detect
// accidental mutations of the original value.
dv.bytes = append([]byte(nil), b...)
}
return dv
}
func unmarshalDefault(b []byte, k pref.Kind, pf *File, ed pref.EnumDescriptor) defaultValue {
var evs pref.EnumValueDescriptors
if k == pref.EnumKind {
// If the enum is declared within the same file, be careful not to
// blindly call the Values method, lest we bind ourselves in a deadlock.
if e, ok := ed.(*Enum); ok && e.L0.ParentFile == pf {
evs = &e.L2.Values
} else {
evs = ed.Values()
}
// If we are unable to resolve the enum dependency, use a placeholder
// enum value since we will not be able to parse the default value.
if ed.IsPlaceholder() && pref.Name(b).IsValid() {
v := pref.ValueOfEnum(0)
ev := PlaceholderEnumValue(ed.FullName().Parent().Append(pref.Name(b)))
return DefaultValue(v, ev)
}
}
v, ev, err := defval.Unmarshal(string(b), k, evs, defval.Descriptor)
if err != nil {
panic(err)
}
return DefaultValue(v, ev)
}
type defaultValue struct {
has bool
val pref.Value
enum pref.EnumValueDescriptor
bytes []byte
}
func (dv *defaultValue) get(fd pref.FieldDescriptor) pref.Value {
// Return the zero value as the default if unpopulated.
if !dv.has {
if fd.Cardinality() == pref.Repeated {
return pref.Value{}
}
switch fd.Kind() {
case pref.BoolKind:
return pref.ValueOfBool(false)
case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
return pref.ValueOfInt32(0)
case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
return pref.ValueOfInt64(0)
case pref.Uint32Kind, pref.Fixed32Kind:
return pref.ValueOfUint32(0)
case pref.Uint64Kind, pref.Fixed64Kind:
return pref.ValueOfUint64(0)
case pref.FloatKind:
return pref.ValueOfFloat32(0)
case pref.DoubleKind:
return pref.ValueOfFloat64(0)
case pref.StringKind:
return pref.ValueOfString("")
case pref.BytesKind:
return pref.ValueOfBytes(nil)
case pref.EnumKind:
if evs := fd.Enum().Values(); evs.Len() > 0 {
return pref.ValueOfEnum(evs.Get(0).Number())
}
return pref.ValueOfEnum(0)
}
}
if len(dv.bytes) > 0 && !bytes.Equal(dv.bytes, dv.val.Bytes()) {
// TODO: Avoid panic if we're running with the race detector
// and instead spawn a goroutine that periodically resets
// this value back to the original to induce a race.
panic("detected mutation on the default bytes")
}
return dv.val
}

View file

@ -0,0 +1,471 @@
// 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 filedesc
import (
"sync"
"google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/internal/fieldnum"
"google.golang.org/protobuf/internal/strs"
pref "google.golang.org/protobuf/reflect/protoreflect"
)
// fileRaw is a data struct used when initializing a file descriptor from
// a raw FileDescriptorProto.
type fileRaw struct {
builder Builder
allEnums []Enum
allMessages []Message
allExtensions []Extension
allServices []Service
}
func newRawFile(db Builder) *File {
fd := &File{fileRaw: fileRaw{builder: db}}
fd.initDecls(db.NumEnums, db.NumMessages, db.NumExtensions, db.NumServices)
fd.unmarshalSeed(db.RawDescriptor)
// Extended message targets are eagerly resolved since registration
// needs this information at program init time.
for i := range fd.allExtensions {
xd := &fd.allExtensions[i]
xd.L1.Extendee = fd.resolveMessageDependency(xd.L1.Extendee, listExtTargets, int32(i))
}
fd.checkDecls()
return fd
}
// initDecls pre-allocates slices for the exact number of enums, messages
// (including map entries), extensions, and services declared in the proto file.
// This is done to avoid regrowing the slice, which would change the address
// for any previously seen declaration.
//
// The alloc methods "allocates" slices by pulling from the capacity.
func (fd *File) initDecls(numEnums, numMessages, numExtensions, numServices int32) {
fd.allEnums = make([]Enum, 0, numEnums)
fd.allMessages = make([]Message, 0, numMessages)
fd.allExtensions = make([]Extension, 0, numExtensions)
fd.allServices = make([]Service, 0, numServices)
}
func (fd *File) allocEnums(n int) []Enum {
total := len(fd.allEnums)
es := fd.allEnums[total : total+n]
fd.allEnums = fd.allEnums[:total+n]
return es
}
func (fd *File) allocMessages(n int) []Message {
total := len(fd.allMessages)
ms := fd.allMessages[total : total+n]
fd.allMessages = fd.allMessages[:total+n]
return ms
}
func (fd *File) allocExtensions(n int) []Extension {
total := len(fd.allExtensions)
xs := fd.allExtensions[total : total+n]
fd.allExtensions = fd.allExtensions[:total+n]
return xs
}
func (fd *File) allocServices(n int) []Service {
total := len(fd.allServices)
xs := fd.allServices[total : total+n]
fd.allServices = fd.allServices[:total+n]
return xs
}
// checkDecls performs a sanity check that the expected number of expected
// declarations matches the number that were found in the descriptor proto.
func (fd *File) checkDecls() {
switch {
case len(fd.allEnums) != cap(fd.allEnums):
case len(fd.allMessages) != cap(fd.allMessages):
case len(fd.allExtensions) != cap(fd.allExtensions):
case len(fd.allServices) != cap(fd.allServices):
default:
return
}
panic("mismatching cardinality")
}
func (fd *File) unmarshalSeed(b []byte) {
sb := getBuilder()
defer putBuilder(sb)
var prevField pref.FieldNumber
var numEnums, numMessages, numExtensions, numServices int
var posEnums, posMessages, posExtensions, posServices int
b0 := b
for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b)
b = b[n:]
switch typ {
case protowire.BytesType:
v, m := protowire.ConsumeBytes(b)
b = b[m:]
switch num {
case fieldnum.FileDescriptorProto_Syntax:
switch string(v) {
case "proto2":
fd.L1.Syntax = pref.Proto2
case "proto3":
fd.L1.Syntax = pref.Proto3
default:
panic("invalid syntax")
}
case fieldnum.FileDescriptorProto_Name:
fd.L1.Path = sb.MakeString(v)
case fieldnum.FileDescriptorProto_Package:
fd.L1.Package = pref.FullName(sb.MakeString(v))
case fieldnum.FileDescriptorProto_EnumType:
if prevField != fieldnum.FileDescriptorProto_EnumType {
if numEnums > 0 {
panic("non-contiguous repeated field")
}
posEnums = len(b0) - len(b) - n - m
}
numEnums++
case fieldnum.FileDescriptorProto_MessageType:
if prevField != fieldnum.FileDescriptorProto_MessageType {
if numMessages > 0 {
panic("non-contiguous repeated field")
}
posMessages = len(b0) - len(b) - n - m
}
numMessages++
case fieldnum.FileDescriptorProto_Extension:
if prevField != fieldnum.FileDescriptorProto_Extension {
if numExtensions > 0 {
panic("non-contiguous repeated field")
}
posExtensions = len(b0) - len(b) - n - m
}
numExtensions++
case fieldnum.FileDescriptorProto_Service:
if prevField != fieldnum.FileDescriptorProto_Service {
if numServices > 0 {
panic("non-contiguous repeated field")
}
posServices = len(b0) - len(b) - n - m
}
numServices++
}
prevField = num
default:
m := protowire.ConsumeFieldValue(num, typ, b)
b = b[m:]
prevField = -1 // ignore known field numbers of unknown wire type
}
}
// If syntax is missing, it is assumed to be proto2.
if fd.L1.Syntax == 0 {
fd.L1.Syntax = pref.Proto2
}
// Must allocate all declarations before parsing each descriptor type
// to ensure we handled all descriptors in "flattened ordering".
if numEnums > 0 {
fd.L1.Enums.List = fd.allocEnums(numEnums)
}
if numMessages > 0 {
fd.L1.Messages.List = fd.allocMessages(numMessages)
}
if numExtensions > 0 {
fd.L1.Extensions.List = fd.allocExtensions(numExtensions)
}
if numServices > 0 {
fd.L1.Services.List = fd.allocServices(numServices)
}
if numEnums > 0 {
b := b0[posEnums:]
for i := range fd.L1.Enums.List {
_, n := protowire.ConsumeVarint(b)
v, m := protowire.ConsumeBytes(b[n:])
fd.L1.Enums.List[i].unmarshalSeed(v, sb, fd, fd, i)
b = b[n+m:]
}
}
if numMessages > 0 {
b := b0[posMessages:]
for i := range fd.L1.Messages.List {
_, n := protowire.ConsumeVarint(b)
v, m := protowire.ConsumeBytes(b[n:])
fd.L1.Messages.List[i].unmarshalSeed(v, sb, fd, fd, i)
b = b[n+m:]
}
}
if numExtensions > 0 {
b := b0[posExtensions:]
for i := range fd.L1.Extensions.List {
_, n := protowire.ConsumeVarint(b)
v, m := protowire.ConsumeBytes(b[n:])
fd.L1.Extensions.List[i].unmarshalSeed(v, sb, fd, fd, i)
b = b[n+m:]
}
}
if numServices > 0 {
b := b0[posServices:]
for i := range fd.L1.Services.List {
_, n := protowire.ConsumeVarint(b)
v, m := protowire.ConsumeBytes(b[n:])
fd.L1.Services.List[i].unmarshalSeed(v, sb, fd, fd, i)
b = b[n+m:]
}
}
}
func (ed *Enum) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
ed.L0.ParentFile = pf
ed.L0.Parent = pd
ed.L0.Index = i
var numValues int
for b := b; len(b) > 0; {
num, typ, n := protowire.ConsumeTag(b)
b = b[n:]
switch typ {
case protowire.BytesType:
v, m := protowire.ConsumeBytes(b)
b = b[m:]
switch num {
case fieldnum.EnumDescriptorProto_Name:
ed.L0.FullName = appendFullName(sb, pd.FullName(), v)
case fieldnum.EnumDescriptorProto_Value:
numValues++
}
default:
m := protowire.ConsumeFieldValue(num, typ, b)
b = b[m:]
}
}
// Only construct enum value descriptors for top-level enums since
// they are needed for registration.
if pd != pf {
return
}
ed.L1.eagerValues = true
ed.L2 = new(EnumL2)
ed.L2.Values.List = make([]EnumValue, numValues)
for i := 0; len(b) > 0; {
num, typ, n := protowire.ConsumeTag(b)
b = b[n:]
switch typ {
case protowire.BytesType:
v, m := protowire.ConsumeBytes(b)
b = b[m:]
switch num {
case fieldnum.EnumDescriptorProto_Value:
ed.L2.Values.List[i].unmarshalFull(v, sb, pf, ed, i)
i++
}
default:
m := protowire.ConsumeFieldValue(num, typ, b)
b = b[m:]
}
}
}
func (md *Message) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
md.L0.ParentFile = pf
md.L0.Parent = pd
md.L0.Index = i
var prevField pref.FieldNumber
var numEnums, numMessages, numExtensions int
var posEnums, posMessages, posExtensions int
b0 := b
for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b)
b = b[n:]
switch typ {
case protowire.BytesType:
v, m := protowire.ConsumeBytes(b)
b = b[m:]
switch num {
case fieldnum.DescriptorProto_Name:
md.L0.FullName = appendFullName(sb, pd.FullName(), v)
case fieldnum.DescriptorProto_EnumType:
if prevField != fieldnum.DescriptorProto_EnumType {
if numEnums > 0 {
panic("non-contiguous repeated field")
}
posEnums = len(b0) - len(b) - n - m
}
numEnums++
case fieldnum.DescriptorProto_NestedType:
if prevField != fieldnum.DescriptorProto_NestedType {
if numMessages > 0 {
panic("non-contiguous repeated field")
}
posMessages = len(b0) - len(b) - n - m
}
numMessages++
case fieldnum.DescriptorProto_Extension:
if prevField != fieldnum.DescriptorProto_Extension {
if numExtensions > 0 {
panic("non-contiguous repeated field")
}
posExtensions = len(b0) - len(b) - n - m
}
numExtensions++
case fieldnum.DescriptorProto_Options:
md.unmarshalSeedOptions(v)
}
prevField = num
default:
m := protowire.ConsumeFieldValue(num, typ, b)
b = b[m:]
prevField = -1 // ignore known field numbers of unknown wire type
}
}
// Must allocate all declarations before parsing each descriptor type
// to ensure we handled all descriptors in "flattened ordering".
if numEnums > 0 {
md.L1.Enums.List = pf.allocEnums(numEnums)
}
if numMessages > 0 {
md.L1.Messages.List = pf.allocMessages(numMessages)
}
if numExtensions > 0 {
md.L1.Extensions.List = pf.allocExtensions(numExtensions)
}
if numEnums > 0 {
b := b0[posEnums:]
for i := range md.L1.Enums.List {
_, n := protowire.ConsumeVarint(b)
v, m := protowire.ConsumeBytes(b[n:])
md.L1.Enums.List[i].unmarshalSeed(v, sb, pf, md, i)
b = b[n+m:]
}
}
if numMessages > 0 {
b := b0[posMessages:]
for i := range md.L1.Messages.List {
_, n := protowire.ConsumeVarint(b)
v, m := protowire.ConsumeBytes(b[n:])
md.L1.Messages.List[i].unmarshalSeed(v, sb, pf, md, i)
b = b[n+m:]
}
}
if numExtensions > 0 {
b := b0[posExtensions:]
for i := range md.L1.Extensions.List {
_, n := protowire.ConsumeVarint(b)
v, m := protowire.ConsumeBytes(b[n:])
md.L1.Extensions.List[i].unmarshalSeed(v, sb, pf, md, i)
b = b[n+m:]
}
}
}
func (md *Message) unmarshalSeedOptions(b []byte) {
for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b)
b = b[n:]
switch typ {
case protowire.VarintType:
v, m := protowire.ConsumeVarint(b)
b = b[m:]
switch num {
case fieldnum.MessageOptions_MapEntry:
md.L1.IsMapEntry = protowire.DecodeBool(v)
case fieldnum.MessageOptions_MessageSetWireFormat:
md.L1.IsMessageSet = protowire.DecodeBool(v)
}
default:
m := protowire.ConsumeFieldValue(num, typ, b)
b = b[m:]
}
}
}
func (xd *Extension) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
xd.L0.ParentFile = pf
xd.L0.Parent = pd
xd.L0.Index = i
for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b)
b = b[n:]
switch typ {
case protowire.VarintType:
v, m := protowire.ConsumeVarint(b)
b = b[m:]
switch num {
case fieldnum.FieldDescriptorProto_Number:
xd.L1.Number = pref.FieldNumber(v)
case fieldnum.FieldDescriptorProto_Label:
xd.L1.Cardinality = pref.Cardinality(v)
case fieldnum.FieldDescriptorProto_Type:
xd.L1.Kind = pref.Kind(v)
}
case protowire.BytesType:
v, m := protowire.ConsumeBytes(b)
b = b[m:]
switch num {
case fieldnum.FieldDescriptorProto_Name:
xd.L0.FullName = appendFullName(sb, pd.FullName(), v)
case fieldnum.FieldDescriptorProto_Extendee:
xd.L1.Extendee = PlaceholderMessage(makeFullName(sb, v))
}
default:
m := protowire.ConsumeFieldValue(num, typ, b)
b = b[m:]
}
}
}
func (sd *Service) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
sd.L0.ParentFile = pf
sd.L0.Parent = pd
sd.L0.Index = i
for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b)
b = b[n:]
switch typ {
case protowire.BytesType:
v, m := protowire.ConsumeBytes(b)
b = b[m:]
switch num {
case fieldnum.ServiceDescriptorProto_Name:
sd.L0.FullName = appendFullName(sb, pd.FullName(), v)
}
default:
m := protowire.ConsumeFieldValue(num, typ, b)
b = b[m:]
}
}
}
var nameBuilderPool = sync.Pool{
New: func() interface{} { return new(strs.Builder) },
}
func getBuilder() *strs.Builder {
return nameBuilderPool.Get().(*strs.Builder)
}
func putBuilder(b *strs.Builder) {
nameBuilderPool.Put(b)
}
// makeFullName converts b to a protoreflect.FullName,
// where b must start with a leading dot.
func makeFullName(sb *strs.Builder, b []byte) pref.FullName {
if len(b) == 0 || b[0] != '.' {
panic("name reference must be fully qualified")
}
return pref.FullName(sb.MakeString(b[1:]))
}
func appendFullName(sb *strs.Builder, prefix pref.FullName, suffix []byte) pref.FullName {
return sb.AppendFullName(prefix, pref.Name(strs.UnsafeString(suffix)))
}

View file

@ -0,0 +1,695 @@
// 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 filedesc
import (
"reflect"
"sync"
"google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/internal/descopts"
"google.golang.org/protobuf/internal/fieldnum"
"google.golang.org/protobuf/internal/strs"
"google.golang.org/protobuf/proto"
pref "google.golang.org/protobuf/reflect/protoreflect"
)
func (fd *File) lazyRawInit() {
fd.unmarshalFull(fd.builder.RawDescriptor)
fd.resolveMessages()
fd.resolveExtensions()
fd.resolveServices()
}
func (file *File) resolveMessages() {
var depIdx int32
for i := range file.allMessages {
md := &file.allMessages[i]
// Resolve message field dependencies.
for j := range md.L2.Fields.List {
fd := &md.L2.Fields.List[j]
// Weak fields are resolved upon actual use.
if fd.L1.IsWeak {
continue
}
// Resolve message field dependency.
switch fd.L1.Kind {
case pref.EnumKind:
fd.L1.Enum = file.resolveEnumDependency(fd.L1.Enum, listFieldDeps, depIdx)
depIdx++
case pref.MessageKind, pref.GroupKind:
fd.L1.Message = file.resolveMessageDependency(fd.L1.Message, listFieldDeps, depIdx)
depIdx++
}
// Default is resolved here since it depends on Enum being resolved.
if v := fd.L1.Default.val; v.IsValid() {
fd.L1.Default = unmarshalDefault(v.Bytes(), fd.L1.Kind, file, fd.L1.Enum)
}
}
}
}
func (file *File) resolveExtensions() {
var depIdx int32
for i := range file.allExtensions {
xd := &file.allExtensions[i]
// Resolve extension field dependency.
switch xd.L1.Kind {
case pref.EnumKind:
xd.L2.Enum = file.resolveEnumDependency(xd.L2.Enum, listExtDeps, depIdx)
depIdx++
case pref.MessageKind, pref.GroupKind:
xd.L2.Message = file.resolveMessageDependency(xd.L2.Message, listExtDeps, depIdx)
depIdx++
}
// Default is resolved here since it depends on Enum being resolved.
if v := xd.L2.Default.val; v.IsValid() {
xd.L2.Default = unmarshalDefault(v.Bytes(), xd.L1.Kind, file, xd.L2.Enum)
}
}
}
func (file *File) resolveServices() {
var depIdx int32
for i := range file.allServices {
sd := &file.allServices[i]
// Resolve method dependencies.
for j := range sd.L2.Methods.List {
md := &sd.L2.Methods.List[j]
md.L1.Input = file.resolveMessageDependency(md.L1.Input, listMethInDeps, depIdx)
md.L1.Output = file.resolveMessageDependency(md.L1.Output, listMethOutDeps, depIdx)
depIdx++
}
}
}
func (file *File) resolveEnumDependency(ed pref.EnumDescriptor, i, j int32) pref.EnumDescriptor {
r := file.builder.FileRegistry
if r, ok := r.(resolverByIndex); ok {
if ed2 := r.FindEnumByIndex(i, j, file.allEnums, file.allMessages); ed2 != nil {
return ed2
}
}
for i := range file.allEnums {
if ed2 := &file.allEnums[i]; ed2.L0.FullName == ed.FullName() {
return ed2
}
}
if d, _ := r.FindDescriptorByName(ed.FullName()); d != nil {
return d.(pref.EnumDescriptor)
}
return ed
}
func (file *File) resolveMessageDependency(md pref.MessageDescriptor, i, j int32) pref.MessageDescriptor {
r := file.builder.FileRegistry
if r, ok := r.(resolverByIndex); ok {
if md2 := r.FindMessageByIndex(i, j, file.allEnums, file.allMessages); md2 != nil {
return md2
}
}
for i := range file.allMessages {
if md2 := &file.allMessages[i]; md2.L0.FullName == md.FullName() {
return md2
}
}
if d, _ := r.FindDescriptorByName(md.FullName()); d != nil {
return d.(pref.MessageDescriptor)
}
return md
}
func (fd *File) unmarshalFull(b []byte) {
sb := getBuilder()
defer putBuilder(sb)
var enumIdx, messageIdx, extensionIdx, serviceIdx int
var rawOptions []byte
fd.L2 = new(FileL2)
for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b)
b = b[n:]
switch typ {
case protowire.VarintType:
v, m := protowire.ConsumeVarint(b)
b = b[m:]
switch num {
case fieldnum.FileDescriptorProto_PublicDependency:
fd.L2.Imports[v].IsPublic = true
case fieldnum.FileDescriptorProto_WeakDependency:
fd.L2.Imports[v].IsWeak = true
}
case protowire.BytesType:
v, m := protowire.ConsumeBytes(b)
b = b[m:]
switch num {
case fieldnum.FileDescriptorProto_Dependency:
path := sb.MakeString(v)
imp, _ := fd.builder.FileRegistry.FindFileByPath(path)
if imp == nil {
imp = PlaceholderFile(path)
}
fd.L2.Imports = append(fd.L2.Imports, pref.FileImport{FileDescriptor: imp})
case fieldnum.FileDescriptorProto_EnumType:
fd.L1.Enums.List[enumIdx].unmarshalFull(v, sb)
enumIdx++
case fieldnum.FileDescriptorProto_MessageType:
fd.L1.Messages.List[messageIdx].unmarshalFull(v, sb)
messageIdx++
case fieldnum.FileDescriptorProto_Extension:
fd.L1.Extensions.List[extensionIdx].unmarshalFull(v, sb)
extensionIdx++
case fieldnum.FileDescriptorProto_Service:
fd.L1.Services.List[serviceIdx].unmarshalFull(v, sb)
serviceIdx++
case fieldnum.FileDescriptorProto_Options:
rawOptions = appendOptions(rawOptions, v)
}
default:
m := protowire.ConsumeFieldValue(num, typ, b)
b = b[m:]
}
}
fd.L2.Options = fd.builder.optionsUnmarshaler(&descopts.File, rawOptions)
}
func (ed *Enum) unmarshalFull(b []byte, sb *strs.Builder) {
var rawValues [][]byte
var rawOptions []byte
if !ed.L1.eagerValues {
ed.L2 = new(EnumL2)
}
for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b)
b = b[n:]
switch typ {
case protowire.BytesType:
v, m := protowire.ConsumeBytes(b)
b = b[m:]
switch num {
case fieldnum.EnumDescriptorProto_Value:
rawValues = append(rawValues, v)
case fieldnum.EnumDescriptorProto_ReservedName:
ed.L2.ReservedNames.List = append(ed.L2.ReservedNames.List, pref.Name(sb.MakeString(v)))
case fieldnum.EnumDescriptorProto_ReservedRange:
ed.L2.ReservedRanges.List = append(ed.L2.ReservedRanges.List, unmarshalEnumReservedRange(v))
case fieldnum.EnumDescriptorProto_Options:
rawOptions = appendOptions(rawOptions, v)
}
default:
m := protowire.ConsumeFieldValue(num, typ, b)
b = b[m:]
}
}
if !ed.L1.eagerValues && len(rawValues) > 0 {
ed.L2.Values.List = make([]EnumValue, len(rawValues))
for i, b := range rawValues {
ed.L2.Values.List[i].unmarshalFull(b, sb, ed.L0.ParentFile, ed, i)
}
}
ed.L2.Options = ed.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Enum, rawOptions)
}
func unmarshalEnumReservedRange(b []byte) (r [2]pref.EnumNumber) {
for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b)
b = b[n:]
switch typ {
case protowire.VarintType:
v, m := protowire.ConsumeVarint(b)
b = b[m:]
switch num {
case fieldnum.EnumDescriptorProto_EnumReservedRange_Start:
r[0] = pref.EnumNumber(v)
case fieldnum.EnumDescriptorProto_EnumReservedRange_End:
r[1] = pref.EnumNumber(v)
}
default:
m := protowire.ConsumeFieldValue(num, typ, b)
b = b[m:]
}
}
return r
}
func (vd *EnumValue) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
vd.L0.ParentFile = pf
vd.L0.Parent = pd
vd.L0.Index = i
var rawOptions []byte
for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b)
b = b[n:]
switch typ {
case protowire.VarintType:
v, m := protowire.ConsumeVarint(b)
b = b[m:]
switch num {
case fieldnum.EnumValueDescriptorProto_Number:
vd.L1.Number = pref.EnumNumber(v)
}
case protowire.BytesType:
v, m := protowire.ConsumeBytes(b)
b = b[m:]
switch num {
case fieldnum.EnumValueDescriptorProto_Name:
// NOTE: Enum values are in the same scope as the enum parent.
vd.L0.FullName = appendFullName(sb, pd.Parent().FullName(), v)
case fieldnum.EnumValueDescriptorProto_Options:
rawOptions = appendOptions(rawOptions, v)
}
default:
m := protowire.ConsumeFieldValue(num, typ, b)
b = b[m:]
}
}
vd.L1.Options = pf.builder.optionsUnmarshaler(&descopts.EnumValue, rawOptions)
}
func (md *Message) unmarshalFull(b []byte, sb *strs.Builder) {
var rawFields, rawOneofs [][]byte
var enumIdx, messageIdx, extensionIdx int
var rawOptions []byte
md.L2 = new(MessageL2)
for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b)
b = b[n:]
switch typ {
case protowire.BytesType:
v, m := protowire.ConsumeBytes(b)
b = b[m:]
switch num {
case fieldnum.DescriptorProto_Field:
rawFields = append(rawFields, v)
case fieldnum.DescriptorProto_OneofDecl:
rawOneofs = append(rawOneofs, v)
case fieldnum.DescriptorProto_ReservedName:
md.L2.ReservedNames.List = append(md.L2.ReservedNames.List, pref.Name(sb.MakeString(v)))
case fieldnum.DescriptorProto_ReservedRange:
md.L2.ReservedRanges.List = append(md.L2.ReservedRanges.List, unmarshalMessageReservedRange(v))
case fieldnum.DescriptorProto_ExtensionRange:
r, rawOptions := unmarshalMessageExtensionRange(v)
opts := md.L0.ParentFile.builder.optionsUnmarshaler(&descopts.ExtensionRange, rawOptions)
md.L2.ExtensionRanges.List = append(md.L2.ExtensionRanges.List, r)
md.L2.ExtensionRangeOptions = append(md.L2.ExtensionRangeOptions, opts)
case fieldnum.DescriptorProto_EnumType:
md.L1.Enums.List[enumIdx].unmarshalFull(v, sb)
enumIdx++
case fieldnum.DescriptorProto_NestedType:
md.L1.Messages.List[messageIdx].unmarshalFull(v, sb)
messageIdx++
case fieldnum.DescriptorProto_Extension:
md.L1.Extensions.List[extensionIdx].unmarshalFull(v, sb)
extensionIdx++
case fieldnum.DescriptorProto_Options:
md.unmarshalOptions(v)
rawOptions = appendOptions(rawOptions, v)
}
default:
m := protowire.ConsumeFieldValue(num, typ, b)
b = b[m:]
}
}
if len(rawFields) > 0 || len(rawOneofs) > 0 {
md.L2.Fields.List = make([]Field, len(rawFields))
md.L2.Oneofs.List = make([]Oneof, len(rawOneofs))
for i, b := range rawFields {
fd := &md.L2.Fields.List[i]
fd.unmarshalFull(b, sb, md.L0.ParentFile, md, i)
if fd.L1.Cardinality == pref.Required {
md.L2.RequiredNumbers.List = append(md.L2.RequiredNumbers.List, fd.L1.Number)
}
}
for i, b := range rawOneofs {
od := &md.L2.Oneofs.List[i]
od.unmarshalFull(b, sb, md.L0.ParentFile, md, i)
}
}
md.L2.Options = md.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Message, rawOptions)
}
func (md *Message) unmarshalOptions(b []byte) {
for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b)
b = b[n:]
switch typ {
case protowire.VarintType:
v, m := protowire.ConsumeVarint(b)
b = b[m:]
switch num {
case fieldnum.MessageOptions_MapEntry:
md.L1.IsMapEntry = protowire.DecodeBool(v)
case fieldnum.MessageOptions_MessageSetWireFormat:
md.L1.IsMessageSet = protowire.DecodeBool(v)
}
default:
m := protowire.ConsumeFieldValue(num, typ, b)
b = b[m:]
}
}
}
func unmarshalMessageReservedRange(b []byte) (r [2]pref.FieldNumber) {
for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b)
b = b[n:]
switch typ {
case protowire.VarintType:
v, m := protowire.ConsumeVarint(b)
b = b[m:]
switch num {
case fieldnum.DescriptorProto_ReservedRange_Start:
r[0] = pref.FieldNumber(v)
case fieldnum.DescriptorProto_ReservedRange_End:
r[1] = pref.FieldNumber(v)
}
default:
m := protowire.ConsumeFieldValue(num, typ, b)
b = b[m:]
}
}
return r
}
func unmarshalMessageExtensionRange(b []byte) (r [2]pref.FieldNumber, rawOptions []byte) {
for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b)
b = b[n:]
switch typ {
case protowire.VarintType:
v, m := protowire.ConsumeVarint(b)
b = b[m:]
switch num {
case fieldnum.DescriptorProto_ExtensionRange_Start:
r[0] = pref.FieldNumber(v)
case fieldnum.DescriptorProto_ExtensionRange_End:
r[1] = pref.FieldNumber(v)
}
case protowire.BytesType:
v, m := protowire.ConsumeBytes(b)
b = b[m:]
switch num {
case fieldnum.DescriptorProto_ExtensionRange_Options:
rawOptions = appendOptions(rawOptions, v)
}
default:
m := protowire.ConsumeFieldValue(num, typ, b)
b = b[m:]
}
}
return r, rawOptions
}
func (fd *Field) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
fd.L0.ParentFile = pf
fd.L0.Parent = pd
fd.L0.Index = i
var rawTypeName []byte
var rawOptions []byte
for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b)
b = b[n:]
switch typ {
case protowire.VarintType:
v, m := protowire.ConsumeVarint(b)
b = b[m:]
switch num {
case fieldnum.FieldDescriptorProto_Number:
fd.L1.Number = pref.FieldNumber(v)
case fieldnum.FieldDescriptorProto_Label:
fd.L1.Cardinality = pref.Cardinality(v)
case fieldnum.FieldDescriptorProto_Type:
fd.L1.Kind = pref.Kind(v)
case fieldnum.FieldDescriptorProto_OneofIndex:
// In Message.unmarshalFull, we allocate slices for both
// the field and oneof descriptors before unmarshaling either
// of them. This ensures pointers to slice elements are stable.
od := &pd.(*Message).L2.Oneofs.List[v]
od.L1.Fields.List = append(od.L1.Fields.List, fd)
if fd.L1.ContainingOneof != nil {
panic("oneof type already set")
}
fd.L1.ContainingOneof = od
}
case protowire.BytesType:
v, m := protowire.ConsumeBytes(b)
b = b[m:]
switch num {
case fieldnum.FieldDescriptorProto_Name:
fd.L0.FullName = appendFullName(sb, pd.FullName(), v)
case fieldnum.FieldDescriptorProto_JsonName:
fd.L1.JSONName.Init(sb.MakeString(v))
case fieldnum.FieldDescriptorProto_DefaultValue:
fd.L1.Default.val = pref.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveMessages
case fieldnum.FieldDescriptorProto_TypeName:
rawTypeName = v
case fieldnum.FieldDescriptorProto_Options:
fd.unmarshalOptions(v)
rawOptions = appendOptions(rawOptions, v)
}
default:
m := protowire.ConsumeFieldValue(num, typ, b)
b = b[m:]
}
}
if rawTypeName != nil {
name := makeFullName(sb, rawTypeName)
switch fd.L1.Kind {
case pref.EnumKind:
fd.L1.Enum = PlaceholderEnum(name)
case pref.MessageKind, pref.GroupKind:
fd.L1.Message = PlaceholderMessage(name)
}
}
fd.L1.Options = pf.builder.optionsUnmarshaler(&descopts.Field, rawOptions)
}
func (fd *Field) unmarshalOptions(b []byte) {
const FieldOptions_EnforceUTF8 = 13
for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b)
b = b[n:]
switch typ {
case protowire.VarintType:
v, m := protowire.ConsumeVarint(b)
b = b[m:]
switch num {
case fieldnum.FieldOptions_Packed:
fd.L1.HasPacked = true
fd.L1.IsPacked = protowire.DecodeBool(v)
case fieldnum.FieldOptions_Weak:
fd.L1.IsWeak = protowire.DecodeBool(v)
case FieldOptions_EnforceUTF8:
fd.L1.HasEnforceUTF8 = true
fd.L1.EnforceUTF8 = protowire.DecodeBool(v)
}
default:
m := protowire.ConsumeFieldValue(num, typ, b)
b = b[m:]
}
}
}
func (od *Oneof) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
od.L0.ParentFile = pf
od.L0.Parent = pd
od.L0.Index = i
var rawOptions []byte
for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b)
b = b[n:]
switch typ {
case protowire.BytesType:
v, m := protowire.ConsumeBytes(b)
b = b[m:]
switch num {
case fieldnum.OneofDescriptorProto_Name:
od.L0.FullName = appendFullName(sb, pd.FullName(), v)
case fieldnum.OneofDescriptorProto_Options:
rawOptions = appendOptions(rawOptions, v)
}
default:
m := protowire.ConsumeFieldValue(num, typ, b)
b = b[m:]
}
}
od.L1.Options = pf.builder.optionsUnmarshaler(&descopts.Oneof, rawOptions)
}
func (xd *Extension) unmarshalFull(b []byte, sb *strs.Builder) {
var rawTypeName []byte
var rawOptions []byte
xd.L2 = new(ExtensionL2)
for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b)
b = b[n:]
switch typ {
case protowire.BytesType:
v, m := protowire.ConsumeBytes(b)
b = b[m:]
switch num {
case fieldnum.FieldDescriptorProto_JsonName:
xd.L2.JSONName.Init(sb.MakeString(v))
case fieldnum.FieldDescriptorProto_DefaultValue:
xd.L2.Default.val = pref.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveExtensions
case fieldnum.FieldDescriptorProto_TypeName:
rawTypeName = v
case fieldnum.FieldDescriptorProto_Options:
xd.unmarshalOptions(v)
rawOptions = appendOptions(rawOptions, v)
}
default:
m := protowire.ConsumeFieldValue(num, typ, b)
b = b[m:]
}
}
if rawTypeName != nil {
name := makeFullName(sb, rawTypeName)
switch xd.L1.Kind {
case pref.EnumKind:
xd.L2.Enum = PlaceholderEnum(name)
case pref.MessageKind, pref.GroupKind:
xd.L2.Message = PlaceholderMessage(name)
}
}
xd.L2.Options = xd.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Field, rawOptions)
}
func (xd *Extension) unmarshalOptions(b []byte) {
for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b)
b = b[n:]
switch typ {
case protowire.VarintType:
v, m := protowire.ConsumeVarint(b)
b = b[m:]
switch num {
case fieldnum.FieldOptions_Packed:
xd.L2.IsPacked = protowire.DecodeBool(v)
}
default:
m := protowire.ConsumeFieldValue(num, typ, b)
b = b[m:]
}
}
}
func (sd *Service) unmarshalFull(b []byte, sb *strs.Builder) {
var rawMethods [][]byte
var rawOptions []byte
sd.L2 = new(ServiceL2)
for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b)
b = b[n:]
switch typ {
case protowire.BytesType:
v, m := protowire.ConsumeBytes(b)
b = b[m:]
switch num {
case fieldnum.ServiceDescriptorProto_Method:
rawMethods = append(rawMethods, v)
case fieldnum.ServiceDescriptorProto_Options:
rawOptions = appendOptions(rawOptions, v)
}
default:
m := protowire.ConsumeFieldValue(num, typ, b)
b = b[m:]
}
}
if len(rawMethods) > 0 {
sd.L2.Methods.List = make([]Method, len(rawMethods))
for i, b := range rawMethods {
sd.L2.Methods.List[i].unmarshalFull(b, sb, sd.L0.ParentFile, sd, i)
}
}
sd.L2.Options = sd.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Service, rawOptions)
}
func (md *Method) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
md.L0.ParentFile = pf
md.L0.Parent = pd
md.L0.Index = i
var rawOptions []byte
for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b)
b = b[n:]
switch typ {
case protowire.VarintType:
v, m := protowire.ConsumeVarint(b)
b = b[m:]
switch num {
case fieldnum.MethodDescriptorProto_ClientStreaming:
md.L1.IsStreamingClient = protowire.DecodeBool(v)
case fieldnum.MethodDescriptorProto_ServerStreaming:
md.L1.IsStreamingServer = protowire.DecodeBool(v)
}
case protowire.BytesType:
v, m := protowire.ConsumeBytes(b)
b = b[m:]
switch num {
case fieldnum.MethodDescriptorProto_Name:
md.L0.FullName = appendFullName(sb, pd.FullName(), v)
case fieldnum.MethodDescriptorProto_InputType:
md.L1.Input = PlaceholderMessage(makeFullName(sb, v))
case fieldnum.MethodDescriptorProto_OutputType:
md.L1.Output = PlaceholderMessage(makeFullName(sb, v))
case fieldnum.MethodDescriptorProto_Options:
rawOptions = appendOptions(rawOptions, v)
}
default:
m := protowire.ConsumeFieldValue(num, typ, b)
b = b[m:]
}
}
md.L1.Options = pf.builder.optionsUnmarshaler(&descopts.Method, rawOptions)
}
// appendOptions appends src to dst, where the returned slice is never nil.
// This is necessary to distinguish between empty and unpopulated options.
func appendOptions(dst, src []byte) []byte {
if dst == nil {
dst = []byte{}
}
return append(dst, src...)
}
// optionsUnmarshaler constructs a lazy unmarshal function for an options message.
//
// The type of message to unmarshal to is passed as a pointer since the
// vars in descopts may not yet be populated at the time this function is called.
func (db *Builder) optionsUnmarshaler(p *pref.ProtoMessage, b []byte) func() pref.ProtoMessage {
if b == nil {
return nil
}
var opts pref.ProtoMessage
var once sync.Once
return func() pref.ProtoMessage {
once.Do(func() {
if *p == nil {
panic("Descriptor.Options called without importing the descriptor package")
}
opts = reflect.New(reflect.TypeOf(*p).Elem()).Interface().(pref.ProtoMessage)
if err := (proto.UnmarshalOptions{
AllowPartial: true,
Resolver: db.TypeResolver,
}).Unmarshal(b, opts); err != nil {
panic(err)
}
})
return opts
}
}

View file

@ -0,0 +1,286 @@
// 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 filedesc
import (
"fmt"
"math"
"sort"
"sync"
"google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/internal/descfmt"
"google.golang.org/protobuf/internal/errors"
"google.golang.org/protobuf/internal/pragma"
"google.golang.org/protobuf/reflect/protoreflect"
pref "google.golang.org/protobuf/reflect/protoreflect"
)
type FileImports []pref.FileImport
func (p *FileImports) Len() int { return len(*p) }
func (p *FileImports) Get(i int) pref.FileImport { return (*p)[i] }
func (p *FileImports) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
func (p *FileImports) ProtoInternal(pragma.DoNotImplement) {}
type Names struct {
List []pref.Name
once sync.Once
has map[pref.Name]int // protected by once
}
func (p *Names) Len() int { return len(p.List) }
func (p *Names) Get(i int) pref.Name { return p.List[i] }
func (p *Names) Has(s pref.Name) bool { return p.lazyInit().has[s] > 0 }
func (p *Names) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
func (p *Names) ProtoInternal(pragma.DoNotImplement) {}
func (p *Names) lazyInit() *Names {
p.once.Do(func() {
if len(p.List) > 0 {
p.has = make(map[pref.Name]int, len(p.List))
for _, s := range p.List {
p.has[s] = p.has[s] + 1
}
}
})
return p
}
// CheckValid reports any errors with the set of names with an error message
// that completes the sentence: "ranges is invalid because it has ..."
func (p *Names) CheckValid() error {
for s, n := range p.lazyInit().has {
switch {
case n > 1:
return errors.New("duplicate name: %q", s)
case false && !s.IsValid():
// NOTE: The C++ implementation does not validate the identifier.
// See https://github.com/protocolbuffers/protobuf/issues/6335.
return errors.New("invalid name: %q", s)
}
}
return nil
}
type EnumRanges struct {
List [][2]pref.EnumNumber // start inclusive; end inclusive
once sync.Once
sorted [][2]pref.EnumNumber // protected by once
}
func (p *EnumRanges) Len() int { return len(p.List) }
func (p *EnumRanges) Get(i int) [2]pref.EnumNumber { return p.List[i] }
func (p *EnumRanges) Has(n pref.EnumNumber) bool {
for ls := p.lazyInit().sorted; len(ls) > 0; {
i := len(ls) / 2
switch r := enumRange(ls[i]); {
case n < r.Start():
ls = ls[:i] // search lower
case n > r.End():
ls = ls[i+1:] // search upper
default:
return true
}
}
return false
}
func (p *EnumRanges) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
func (p *EnumRanges) ProtoInternal(pragma.DoNotImplement) {}
func (p *EnumRanges) lazyInit() *EnumRanges {
p.once.Do(func() {
p.sorted = append(p.sorted, p.List...)
sort.Slice(p.sorted, func(i, j int) bool {
return p.sorted[i][0] < p.sorted[j][0]
})
})
return p
}
// CheckValid reports any errors with the set of names with an error message
// that completes the sentence: "ranges is invalid because it has ..."
func (p *EnumRanges) CheckValid() error {
var rp enumRange
for i, r := range p.lazyInit().sorted {
r := enumRange(r)
switch {
case !(r.Start() <= r.End()):
return errors.New("invalid range: %v", r)
case !(rp.End() < r.Start()) && i > 0:
return errors.New("overlapping ranges: %v with %v", rp, r)
}
rp = r
}
return nil
}
type enumRange [2]protoreflect.EnumNumber
func (r enumRange) Start() protoreflect.EnumNumber { return r[0] } // inclusive
func (r enumRange) End() protoreflect.EnumNumber { return r[1] } // inclusive
func (r enumRange) String() string {
if r.Start() == r.End() {
return fmt.Sprintf("%d", r.Start())
}
return fmt.Sprintf("%d to %d", r.Start(), r.End())
}
type FieldRanges struct {
List [][2]pref.FieldNumber // start inclusive; end exclusive
once sync.Once
sorted [][2]pref.FieldNumber // protected by once
}
func (p *FieldRanges) Len() int { return len(p.List) }
func (p *FieldRanges) Get(i int) [2]pref.FieldNumber { return p.List[i] }
func (p *FieldRanges) Has(n pref.FieldNumber) bool {
for ls := p.lazyInit().sorted; len(ls) > 0; {
i := len(ls) / 2
switch r := fieldRange(ls[i]); {
case n < r.Start():
ls = ls[:i] // search lower
case n > r.End():
ls = ls[i+1:] // search upper
default:
return true
}
}
return false
}
func (p *FieldRanges) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
func (p *FieldRanges) ProtoInternal(pragma.DoNotImplement) {}
func (p *FieldRanges) lazyInit() *FieldRanges {
p.once.Do(func() {
p.sorted = append(p.sorted, p.List...)
sort.Slice(p.sorted, func(i, j int) bool {
return p.sorted[i][0] < p.sorted[j][0]
})
})
return p
}
// CheckValid reports any errors with the set of ranges with an error message
// that completes the sentence: "ranges is invalid because it has ..."
func (p *FieldRanges) CheckValid(isMessageSet bool) error {
var rp fieldRange
for i, r := range p.lazyInit().sorted {
r := fieldRange(r)
switch {
case !isValidFieldNumber(r.Start(), isMessageSet):
return errors.New("invalid field number: %d", r.Start())
case !isValidFieldNumber(r.End(), isMessageSet):
return errors.New("invalid field number: %d", r.End())
case !(r.Start() <= r.End()):
return errors.New("invalid range: %v", r)
case !(rp.End() < r.Start()) && i > 0:
return errors.New("overlapping ranges: %v with %v", rp, r)
}
rp = r
}
return nil
}
// isValidFieldNumber reports whether the field number is valid.
// Unlike the FieldNumber.IsValid method, it allows ranges that cover the
// reserved number range.
func isValidFieldNumber(n protoreflect.FieldNumber, isMessageSet bool) bool {
if isMessageSet {
return protowire.MinValidNumber <= n && n <= math.MaxInt32
}
return protowire.MinValidNumber <= n && n <= protowire.MaxValidNumber
}
// CheckOverlap reports an error if p and q overlap.
func (p *FieldRanges) CheckOverlap(q *FieldRanges) error {
rps := p.lazyInit().sorted
rqs := q.lazyInit().sorted
for pi, qi := 0, 0; pi < len(rps) && qi < len(rqs); {
rp := fieldRange(rps[pi])
rq := fieldRange(rqs[qi])
if !(rp.End() < rq.Start() || rq.End() < rp.Start()) {
return errors.New("overlapping ranges: %v with %v", rp, rq)
}
if rp.Start() < rq.Start() {
pi++
} else {
qi++
}
}
return nil
}
type fieldRange [2]protoreflect.FieldNumber
func (r fieldRange) Start() protoreflect.FieldNumber { return r[0] } // inclusive
func (r fieldRange) End() protoreflect.FieldNumber { return r[1] - 1 } // inclusive
func (r fieldRange) String() string {
if r.Start() == r.End() {
return fmt.Sprintf("%d", r.Start())
}
return fmt.Sprintf("%d to %d", r.Start(), r.End())
}
type FieldNumbers struct {
List []pref.FieldNumber
once sync.Once
has map[pref.FieldNumber]struct{} // protected by once
}
func (p *FieldNumbers) Len() int { return len(p.List) }
func (p *FieldNumbers) Get(i int) pref.FieldNumber { return p.List[i] }
func (p *FieldNumbers) Has(n pref.FieldNumber) bool {
p.once.Do(func() {
if len(p.List) > 0 {
p.has = make(map[pref.FieldNumber]struct{}, len(p.List))
for _, n := range p.List {
p.has[n] = struct{}{}
}
}
})
_, ok := p.has[n]
return ok
}
func (p *FieldNumbers) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
func (p *FieldNumbers) ProtoInternal(pragma.DoNotImplement) {}
type OneofFields struct {
List []pref.FieldDescriptor
once sync.Once
byName map[pref.Name]pref.FieldDescriptor // protected by once
byJSON map[string]pref.FieldDescriptor // protected by once
byNum map[pref.FieldNumber]pref.FieldDescriptor // protected by once
}
func (p *OneofFields) Len() int { return len(p.List) }
func (p *OneofFields) Get(i int) pref.FieldDescriptor { return p.List[i] }
func (p *OneofFields) ByName(s pref.Name) pref.FieldDescriptor { return p.lazyInit().byName[s] }
func (p *OneofFields) ByJSONName(s string) pref.FieldDescriptor { return p.lazyInit().byJSON[s] }
func (p *OneofFields) ByNumber(n pref.FieldNumber) pref.FieldDescriptor { return p.lazyInit().byNum[n] }
func (p *OneofFields) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
func (p *OneofFields) ProtoInternal(pragma.DoNotImplement) {}
func (p *OneofFields) lazyInit() *OneofFields {
p.once.Do(func() {
if len(p.List) > 0 {
p.byName = make(map[pref.Name]pref.FieldDescriptor, len(p.List))
p.byJSON = make(map[string]pref.FieldDescriptor, len(p.List))
p.byNum = make(map[pref.FieldNumber]pref.FieldDescriptor, len(p.List))
for _, f := range p.List {
// Field names and numbers are guaranteed to be unique.
p.byName[f.Name()] = f
p.byJSON[f.JSONName()] = f
p.byNum[f.Number()] = f
}
}
})
return p
}
type SourceLocations struct {
List []pref.SourceLocation
}
func (p *SourceLocations) Len() int { return len(p.List) }
func (p *SourceLocations) Get(i int) pref.SourceLocation { return p.List[i] }
func (p *SourceLocations) ProtoInternal(pragma.DoNotImplement) {}

View file

@ -0,0 +1,345 @@
// 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.
// Code generated by generate-types. DO NOT EDIT.
package filedesc
import (
"fmt"
"sync"
"google.golang.org/protobuf/internal/descfmt"
"google.golang.org/protobuf/internal/pragma"
"google.golang.org/protobuf/reflect/protoreflect"
)
type Enums struct {
List []Enum
once sync.Once
byName map[protoreflect.Name]*Enum // protected by once
}
func (p *Enums) Len() int {
return len(p.List)
}
func (p *Enums) Get(i int) protoreflect.EnumDescriptor {
return &p.List[i]
}
func (p *Enums) ByName(s protoreflect.Name) protoreflect.EnumDescriptor {
if d := p.lazyInit().byName[s]; d != nil {
return d
}
return nil
}
func (p *Enums) Format(s fmt.State, r rune) {
descfmt.FormatList(s, r, p)
}
func (p *Enums) ProtoInternal(pragma.DoNotImplement) {}
func (p *Enums) lazyInit() *Enums {
p.once.Do(func() {
if len(p.List) > 0 {
p.byName = make(map[protoreflect.Name]*Enum, len(p.List))
for i := range p.List {
d := &p.List[i]
if _, ok := p.byName[d.Name()]; !ok {
p.byName[d.Name()] = d
}
}
}
})
return p
}
type EnumValues struct {
List []EnumValue
once sync.Once
byName map[protoreflect.Name]*EnumValue // protected by once
byNum map[protoreflect.EnumNumber]*EnumValue // protected by once
}
func (p *EnumValues) Len() int {
return len(p.List)
}
func (p *EnumValues) Get(i int) protoreflect.EnumValueDescriptor {
return &p.List[i]
}
func (p *EnumValues) ByName(s protoreflect.Name) protoreflect.EnumValueDescriptor {
if d := p.lazyInit().byName[s]; d != nil {
return d
}
return nil
}
func (p *EnumValues) ByNumber(n protoreflect.EnumNumber) protoreflect.EnumValueDescriptor {
if d := p.lazyInit().byNum[n]; d != nil {
return d
}
return nil
}
func (p *EnumValues) Format(s fmt.State, r rune) {
descfmt.FormatList(s, r, p)
}
func (p *EnumValues) ProtoInternal(pragma.DoNotImplement) {}
func (p *EnumValues) lazyInit() *EnumValues {
p.once.Do(func() {
if len(p.List) > 0 {
p.byName = make(map[protoreflect.Name]*EnumValue, len(p.List))
p.byNum = make(map[protoreflect.EnumNumber]*EnumValue, len(p.List))
for i := range p.List {
d := &p.List[i]
if _, ok := p.byName[d.Name()]; !ok {
p.byName[d.Name()] = d
}
if _, ok := p.byNum[d.Number()]; !ok {
p.byNum[d.Number()] = d
}
}
}
})
return p
}
type Messages struct {
List []Message
once sync.Once
byName map[protoreflect.Name]*Message // protected by once
}
func (p *Messages) Len() int {
return len(p.List)
}
func (p *Messages) Get(i int) protoreflect.MessageDescriptor {
return &p.List[i]
}
func (p *Messages) ByName(s protoreflect.Name) protoreflect.MessageDescriptor {
if d := p.lazyInit().byName[s]; d != nil {
return d
}
return nil
}
func (p *Messages) Format(s fmt.State, r rune) {
descfmt.FormatList(s, r, p)
}
func (p *Messages) ProtoInternal(pragma.DoNotImplement) {}
func (p *Messages) lazyInit() *Messages {
p.once.Do(func() {
if len(p.List) > 0 {
p.byName = make(map[protoreflect.Name]*Message, len(p.List))
for i := range p.List {
d := &p.List[i]
if _, ok := p.byName[d.Name()]; !ok {
p.byName[d.Name()] = d
}
}
}
})
return p
}
type Fields struct {
List []Field
once sync.Once
byName map[protoreflect.Name]*Field // protected by once
byJSON map[string]*Field // protected by once
byNum map[protoreflect.FieldNumber]*Field // protected by once
}
func (p *Fields) Len() int {
return len(p.List)
}
func (p *Fields) Get(i int) protoreflect.FieldDescriptor {
return &p.List[i]
}
func (p *Fields) ByName(s protoreflect.Name) protoreflect.FieldDescriptor {
if d := p.lazyInit().byName[s]; d != nil {
return d
}
return nil
}
func (p *Fields) ByJSONName(s string) protoreflect.FieldDescriptor {
if d := p.lazyInit().byJSON[s]; d != nil {
return d
}
return nil
}
func (p *Fields) ByNumber(n protoreflect.FieldNumber) protoreflect.FieldDescriptor {
if d := p.lazyInit().byNum[n]; d != nil {
return d
}
return nil
}
func (p *Fields) Format(s fmt.State, r rune) {
descfmt.FormatList(s, r, p)
}
func (p *Fields) ProtoInternal(pragma.DoNotImplement) {}
func (p *Fields) lazyInit() *Fields {
p.once.Do(func() {
if len(p.List) > 0 {
p.byName = make(map[protoreflect.Name]*Field, len(p.List))
p.byJSON = make(map[string]*Field, len(p.List))
p.byNum = make(map[protoreflect.FieldNumber]*Field, len(p.List))
for i := range p.List {
d := &p.List[i]
if _, ok := p.byName[d.Name()]; !ok {
p.byName[d.Name()] = d
}
if _, ok := p.byJSON[d.JSONName()]; !ok {
p.byJSON[d.JSONName()] = d
}
if _, ok := p.byNum[d.Number()]; !ok {
p.byNum[d.Number()] = d
}
}
}
})
return p
}
type Oneofs struct {
List []Oneof
once sync.Once
byName map[protoreflect.Name]*Oneof // protected by once
}
func (p *Oneofs) Len() int {
return len(p.List)
}
func (p *Oneofs) Get(i int) protoreflect.OneofDescriptor {
return &p.List[i]
}
func (p *Oneofs) ByName(s protoreflect.Name) protoreflect.OneofDescriptor {
if d := p.lazyInit().byName[s]; d != nil {
return d
}
return nil
}
func (p *Oneofs) Format(s fmt.State, r rune) {
descfmt.FormatList(s, r, p)
}
func (p *Oneofs) ProtoInternal(pragma.DoNotImplement) {}
func (p *Oneofs) lazyInit() *Oneofs {
p.once.Do(func() {
if len(p.List) > 0 {
p.byName = make(map[protoreflect.Name]*Oneof, len(p.List))
for i := range p.List {
d := &p.List[i]
if _, ok := p.byName[d.Name()]; !ok {
p.byName[d.Name()] = d
}
}
}
})
return p
}
type Extensions struct {
List []Extension
once sync.Once
byName map[protoreflect.Name]*Extension // protected by once
}
func (p *Extensions) Len() int {
return len(p.List)
}
func (p *Extensions) Get(i int) protoreflect.ExtensionDescriptor {
return &p.List[i]
}
func (p *Extensions) ByName(s protoreflect.Name) protoreflect.ExtensionDescriptor {
if d := p.lazyInit().byName[s]; d != nil {
return d
}
return nil
}
func (p *Extensions) Format(s fmt.State, r rune) {
descfmt.FormatList(s, r, p)
}
func (p *Extensions) ProtoInternal(pragma.DoNotImplement) {}
func (p *Extensions) lazyInit() *Extensions {
p.once.Do(func() {
if len(p.List) > 0 {
p.byName = make(map[protoreflect.Name]*Extension, len(p.List))
for i := range p.List {
d := &p.List[i]
if _, ok := p.byName[d.Name()]; !ok {
p.byName[d.Name()] = d
}
}
}
})
return p
}
type Services struct {
List []Service
once sync.Once
byName map[protoreflect.Name]*Service // protected by once
}
func (p *Services) Len() int {
return len(p.List)
}
func (p *Services) Get(i int) protoreflect.ServiceDescriptor {
return &p.List[i]
}
func (p *Services) ByName(s protoreflect.Name) protoreflect.ServiceDescriptor {
if d := p.lazyInit().byName[s]; d != nil {
return d
}
return nil
}
func (p *Services) Format(s fmt.State, r rune) {
descfmt.FormatList(s, r, p)
}
func (p *Services) ProtoInternal(pragma.DoNotImplement) {}
func (p *Services) lazyInit() *Services {
p.once.Do(func() {
if len(p.List) > 0 {
p.byName = make(map[protoreflect.Name]*Service, len(p.List))
for i := range p.List {
d := &p.List[i]
if _, ok := p.byName[d.Name()]; !ok {
p.byName[d.Name()] = d
}
}
}
})
return p
}
type Methods struct {
List []Method
once sync.Once
byName map[protoreflect.Name]*Method // protected by once
}
func (p *Methods) Len() int {
return len(p.List)
}
func (p *Methods) Get(i int) protoreflect.MethodDescriptor {
return &p.List[i]
}
func (p *Methods) ByName(s protoreflect.Name) protoreflect.MethodDescriptor {
if d := p.lazyInit().byName[s]; d != nil {
return d
}
return nil
}
func (p *Methods) Format(s fmt.State, r rune) {
descfmt.FormatList(s, r, p)
}
func (p *Methods) ProtoInternal(pragma.DoNotImplement) {}
func (p *Methods) lazyInit() *Methods {
p.once.Do(func() {
if len(p.List) > 0 {
p.byName = make(map[protoreflect.Name]*Method, len(p.List))
for i := range p.List {
d := &p.List[i]
if _, ok := p.byName[d.Name()]; !ok {
p.byName[d.Name()] = d
}
}
}
})
return p
}

View file

@ -0,0 +1,107 @@
// 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 filedesc
import (
"google.golang.org/protobuf/internal/descopts"
"google.golang.org/protobuf/internal/pragma"
pref "google.golang.org/protobuf/reflect/protoreflect"
)
var (
emptyNames = new(Names)
emptyEnumRanges = new(EnumRanges)
emptyFieldRanges = new(FieldRanges)
emptyFieldNumbers = new(FieldNumbers)
emptySourceLocations = new(SourceLocations)
emptyFiles = new(FileImports)
emptyMessages = new(Messages)
emptyFields = new(Fields)
emptyOneofs = new(Oneofs)
emptyEnums = new(Enums)
emptyEnumValues = new(EnumValues)
emptyExtensions = new(Extensions)
emptyServices = new(Services)
)
// PlaceholderFile is a placeholder, representing only the file path.
type PlaceholderFile string
func (f PlaceholderFile) ParentFile() pref.FileDescriptor { return f }
func (f PlaceholderFile) Parent() pref.Descriptor { return nil }
func (f PlaceholderFile) Index() int { return 0 }
func (f PlaceholderFile) Syntax() pref.Syntax { return 0 }
func (f PlaceholderFile) Name() pref.Name { return "" }
func (f PlaceholderFile) FullName() pref.FullName { return "" }
func (f PlaceholderFile) IsPlaceholder() bool { return true }
func (f PlaceholderFile) Options() pref.ProtoMessage { return descopts.File }
func (f PlaceholderFile) Path() string { return string(f) }
func (f PlaceholderFile) Package() pref.FullName { return "" }
func (f PlaceholderFile) Imports() pref.FileImports { return emptyFiles }
func (f PlaceholderFile) Messages() pref.MessageDescriptors { return emptyMessages }
func (f PlaceholderFile) Enums() pref.EnumDescriptors { return emptyEnums }
func (f PlaceholderFile) Extensions() pref.ExtensionDescriptors { return emptyExtensions }
func (f PlaceholderFile) Services() pref.ServiceDescriptors { return emptyServices }
func (f PlaceholderFile) SourceLocations() pref.SourceLocations { return emptySourceLocations }
func (f PlaceholderFile) ProtoType(pref.FileDescriptor) { return }
func (f PlaceholderFile) ProtoInternal(pragma.DoNotImplement) { return }
// PlaceholderEnum is a placeholder, representing only the full name.
type PlaceholderEnum pref.FullName
func (e PlaceholderEnum) ParentFile() pref.FileDescriptor { return nil }
func (e PlaceholderEnum) Parent() pref.Descriptor { return nil }
func (e PlaceholderEnum) Index() int { return 0 }
func (e PlaceholderEnum) Syntax() pref.Syntax { return 0 }
func (e PlaceholderEnum) Name() pref.Name { return pref.FullName(e).Name() }
func (e PlaceholderEnum) FullName() pref.FullName { return pref.FullName(e) }
func (e PlaceholderEnum) IsPlaceholder() bool { return true }
func (e PlaceholderEnum) Options() pref.ProtoMessage { return descopts.Enum }
func (e PlaceholderEnum) Values() pref.EnumValueDescriptors { return emptyEnumValues }
func (e PlaceholderEnum) ReservedNames() pref.Names { return emptyNames }
func (e PlaceholderEnum) ReservedRanges() pref.EnumRanges { return emptyEnumRanges }
func (e PlaceholderEnum) ProtoType(pref.EnumDescriptor) { return }
func (e PlaceholderEnum) ProtoInternal(pragma.DoNotImplement) { return }
// PlaceholderEnumValue is a placeholder, representing only the full name.
type PlaceholderEnumValue pref.FullName
func (e PlaceholderEnumValue) ParentFile() pref.FileDescriptor { return nil }
func (e PlaceholderEnumValue) Parent() pref.Descriptor { return nil }
func (e PlaceholderEnumValue) Index() int { return 0 }
func (e PlaceholderEnumValue) Syntax() pref.Syntax { return 0 }
func (e PlaceholderEnumValue) Name() pref.Name { return pref.FullName(e).Name() }
func (e PlaceholderEnumValue) FullName() pref.FullName { return pref.FullName(e) }
func (e PlaceholderEnumValue) IsPlaceholder() bool { return true }
func (e PlaceholderEnumValue) Options() pref.ProtoMessage { return descopts.EnumValue }
func (e PlaceholderEnumValue) Number() pref.EnumNumber { return 0 }
func (e PlaceholderEnumValue) ProtoType(pref.EnumValueDescriptor) { return }
func (e PlaceholderEnumValue) ProtoInternal(pragma.DoNotImplement) { return }
// PlaceholderMessage is a placeholder, representing only the full name.
type PlaceholderMessage pref.FullName
func (m PlaceholderMessage) ParentFile() pref.FileDescriptor { return nil }
func (m PlaceholderMessage) Parent() pref.Descriptor { return nil }
func (m PlaceholderMessage) Index() int { return 0 }
func (m PlaceholderMessage) Syntax() pref.Syntax { return 0 }
func (m PlaceholderMessage) Name() pref.Name { return pref.FullName(m).Name() }
func (m PlaceholderMessage) FullName() pref.FullName { return pref.FullName(m) }
func (m PlaceholderMessage) IsPlaceholder() bool { return true }
func (m PlaceholderMessage) Options() pref.ProtoMessage { return descopts.Message }
func (m PlaceholderMessage) IsMapEntry() bool { return false }
func (m PlaceholderMessage) Fields() pref.FieldDescriptors { return emptyFields }
func (m PlaceholderMessage) Oneofs() pref.OneofDescriptors { return emptyOneofs }
func (m PlaceholderMessage) ReservedNames() pref.Names { return emptyNames }
func (m PlaceholderMessage) ReservedRanges() pref.FieldRanges { return emptyFieldRanges }
func (m PlaceholderMessage) RequiredNumbers() pref.FieldNumbers { return emptyFieldNumbers }
func (m PlaceholderMessage) ExtensionRanges() pref.FieldRanges { return emptyFieldRanges }
func (m PlaceholderMessage) ExtensionRangeOptions(int) pref.ProtoMessage { panic("index out of range") }
func (m PlaceholderMessage) Messages() pref.MessageDescriptors { return emptyMessages }
func (m PlaceholderMessage) Enums() pref.EnumDescriptors { return emptyEnums }
func (m PlaceholderMessage) Extensions() pref.ExtensionDescriptors { return emptyExtensions }
func (m PlaceholderMessage) ProtoType(pref.MessageDescriptor) { return }
func (m PlaceholderMessage) ProtoInternal(pragma.DoNotImplement) { return }