package protodesc
import (
"google.golang.org/protobuf/internal/errors"
"google.golang.org/protobuf/internal/filedesc"
"google.golang.org/protobuf/internal/strs"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/types/descriptorpb"
)
type descsByName map [protoreflect .FullName ]protoreflect .Descriptor
func (r descsByName ) initEnumDeclarations (eds []*descriptorpb .EnumDescriptorProto , parent protoreflect .Descriptor , sb *strs .Builder ) (es []filedesc .Enum , err error ) {
es = make ([]filedesc .Enum , len (eds ))
for i , ed := range eds {
e := &es [i ]
e .L2 = new (filedesc .EnumL2 )
if e .L0 , err = r .makeBase (e , parent , ed .GetName (), i , sb ); err != nil {
return nil , err
}
if opts := ed .GetOptions (); opts != nil {
opts = proto .Clone (opts ).(*descriptorpb .EnumOptions )
e .L2 .Options = func () protoreflect .ProtoMessage { return opts }
}
e .L1 .EditionFeatures = mergeEditionFeatures (parent , ed .GetOptions ().GetFeatures ())
for _ , s := range ed .GetReservedName () {
e .L2 .ReservedNames .List = append (e .L2 .ReservedNames .List , protoreflect .Name (s ))
}
for _ , rr := range ed .GetReservedRange () {
e .L2 .ReservedRanges .List = append (e .L2 .ReservedRanges .List , [2 ]protoreflect .EnumNumber {
protoreflect .EnumNumber (rr .GetStart ()),
protoreflect .EnumNumber (rr .GetEnd ()),
})
}
if e .L2 .Values .List , err = r .initEnumValuesFromDescriptorProto (ed .GetValue (), e , sb ); err != nil {
return nil , err
}
}
return es , nil
}
func (r descsByName ) initEnumValuesFromDescriptorProto (vds []*descriptorpb .EnumValueDescriptorProto , parent protoreflect .Descriptor , sb *strs .Builder ) (vs []filedesc .EnumValue , err error ) {
vs = make ([]filedesc .EnumValue , len (vds ))
for i , vd := range vds {
v := &vs [i ]
if v .L0 , err = r .makeBase (v , parent , vd .GetName (), i , sb ); err != nil {
return nil , err
}
if opts := vd .GetOptions (); opts != nil {
opts = proto .Clone (opts ).(*descriptorpb .EnumValueOptions )
v .L1 .Options = func () protoreflect .ProtoMessage { return opts }
}
v .L1 .Number = protoreflect .EnumNumber (vd .GetNumber ())
}
return vs , nil
}
func (r descsByName ) initMessagesDeclarations (mds []*descriptorpb .DescriptorProto , parent protoreflect .Descriptor , sb *strs .Builder ) (ms []filedesc .Message , err error ) {
ms = make ([]filedesc .Message , len (mds ))
for i , md := range mds {
m := &ms [i ]
m .L2 = new (filedesc .MessageL2 )
if m .L0 , err = r .makeBase (m , parent , md .GetName (), i , sb ); err != nil {
return nil , err
}
m .L1 .EditionFeatures = mergeEditionFeatures (parent , md .GetOptions ().GetFeatures ())
if opts := md .GetOptions (); opts != nil {
opts = proto .Clone (opts ).(*descriptorpb .MessageOptions )
m .L2 .Options = func () protoreflect .ProtoMessage { return opts }
m .L1 .IsMapEntry = opts .GetMapEntry ()
m .L1 .IsMessageSet = opts .GetMessageSetWireFormat ()
}
for _ , s := range md .GetReservedName () {
m .L2 .ReservedNames .List = append (m .L2 .ReservedNames .List , protoreflect .Name (s ))
}
for _ , rr := range md .GetReservedRange () {
m .L2 .ReservedRanges .List = append (m .L2 .ReservedRanges .List , [2 ]protoreflect .FieldNumber {
protoreflect .FieldNumber (rr .GetStart ()),
protoreflect .FieldNumber (rr .GetEnd ()),
})
}
for _ , xr := range md .GetExtensionRange () {
m .L2 .ExtensionRanges .List = append (m .L2 .ExtensionRanges .List , [2 ]protoreflect .FieldNumber {
protoreflect .FieldNumber (xr .GetStart ()),
protoreflect .FieldNumber (xr .GetEnd ()),
})
var optsFunc func () protoreflect .ProtoMessage
if opts := xr .GetOptions (); opts != nil {
opts = proto .Clone (opts ).(*descriptorpb .ExtensionRangeOptions )
optsFunc = func () protoreflect .ProtoMessage { return opts }
}
m .L2 .ExtensionRangeOptions = append (m .L2 .ExtensionRangeOptions , optsFunc )
}
if m .L2 .Fields .List , err = r .initFieldsFromDescriptorProto (md .GetField (), m , sb ); err != nil {
return nil , err
}
if m .L2 .Oneofs .List , err = r .initOneofsFromDescriptorProto (md .GetOneofDecl (), m , sb ); err != nil {
return nil , err
}
if m .L1 .Enums .List , err = r .initEnumDeclarations (md .GetEnumType (), m , sb ); err != nil {
return nil , err
}
if m .L1 .Messages .List , err = r .initMessagesDeclarations (md .GetNestedType (), m , sb ); err != nil {
return nil , err
}
if m .L1 .Extensions .List , err = r .initExtensionDeclarations (md .GetExtension (), m , sb ); err != nil {
return nil , err
}
}
return ms , nil
}
func canBePacked(fd *descriptorpb .FieldDescriptorProto ) bool {
if fd .GetLabel () != descriptorpb .FieldDescriptorProto_LABEL_REPEATED {
return false
}
switch protoreflect .Kind (fd .GetType ()) {
case protoreflect .MessageKind , protoreflect .GroupKind :
return false
case protoreflect .StringKind , protoreflect .BytesKind :
return false
default :
return true
}
}
func (r descsByName ) initFieldsFromDescriptorProto (fds []*descriptorpb .FieldDescriptorProto , parent protoreflect .Descriptor , sb *strs .Builder ) (fs []filedesc .Field , err error ) {
fs = make ([]filedesc .Field , len (fds ))
for i , fd := range fds {
f := &fs [i ]
if f .L0 , err = r .makeBase (f , parent , fd .GetName (), i , sb ); err != nil {
return nil , err
}
f .L1 .EditionFeatures = mergeEditionFeatures (parent , fd .GetOptions ().GetFeatures ())
f .L1 .IsProto3Optional = fd .GetProto3Optional ()
if opts := fd .GetOptions (); opts != nil {
opts = proto .Clone (opts ).(*descriptorpb .FieldOptions )
f .L1 .Options = func () protoreflect .ProtoMessage { return opts }
f .L1 .IsLazy = opts .GetLazy ()
if opts .Packed != nil {
f .L1 .EditionFeatures .IsPacked = opts .GetPacked ()
}
}
f .L1 .Number = protoreflect .FieldNumber (fd .GetNumber ())
f .L1 .Cardinality = protoreflect .Cardinality (fd .GetLabel ())
if fd .Type != nil {
f .L1 .Kind = protoreflect .Kind (fd .GetType ())
}
if fd .JsonName != nil {
f .L1 .StringName .InitJSON (fd .GetJsonName ())
}
if f .L1 .EditionFeatures .IsLegacyRequired {
f .L1 .Cardinality = protoreflect .Required
}
if f .L1 .Kind == protoreflect .MessageKind && f .L1 .EditionFeatures .IsDelimitedEncoded {
f .L1 .Kind = protoreflect .GroupKind
}
}
return fs , nil
}
func (r descsByName ) initOneofsFromDescriptorProto (ods []*descriptorpb .OneofDescriptorProto , parent protoreflect .Descriptor , sb *strs .Builder ) (os []filedesc .Oneof , err error ) {
os = make ([]filedesc .Oneof , len (ods ))
for i , od := range ods {
o := &os [i ]
if o .L0 , err = r .makeBase (o , parent , od .GetName (), i , sb ); err != nil {
return nil , err
}
o .L1 .EditionFeatures = mergeEditionFeatures (parent , od .GetOptions ().GetFeatures ())
if opts := od .GetOptions (); opts != nil {
opts = proto .Clone (opts ).(*descriptorpb .OneofOptions )
o .L1 .Options = func () protoreflect .ProtoMessage { return opts }
}
}
return os , nil
}
func (r descsByName ) initExtensionDeclarations (xds []*descriptorpb .FieldDescriptorProto , parent protoreflect .Descriptor , sb *strs .Builder ) (xs []filedesc .Extension , err error ) {
xs = make ([]filedesc .Extension , len (xds ))
for i , xd := range xds {
x := &xs [i ]
x .L2 = new (filedesc .ExtensionL2 )
if x .L0 , err = r .makeBase (x , parent , xd .GetName (), i , sb ); err != nil {
return nil , err
}
x .L1 .EditionFeatures = mergeEditionFeatures (parent , xd .GetOptions ().GetFeatures ())
if opts := xd .GetOptions (); opts != nil {
opts = proto .Clone (opts ).(*descriptorpb .FieldOptions )
x .L2 .Options = func () protoreflect .ProtoMessage { return opts }
if opts .Packed != nil {
x .L1 .EditionFeatures .IsPacked = opts .GetPacked ()
}
}
x .L1 .Number = protoreflect .FieldNumber (xd .GetNumber ())
x .L1 .Cardinality = protoreflect .Cardinality (xd .GetLabel ())
if xd .Type != nil {
x .L1 .Kind = protoreflect .Kind (xd .GetType ())
}
if xd .JsonName != nil {
x .L2 .StringName .InitJSON (xd .GetJsonName ())
}
if x .L1 .Kind == protoreflect .MessageKind && x .L1 .EditionFeatures .IsDelimitedEncoded {
x .L1 .Kind = protoreflect .GroupKind
}
}
return xs , nil
}
func (r descsByName ) initServiceDeclarations (sds []*descriptorpb .ServiceDescriptorProto , parent protoreflect .Descriptor , sb *strs .Builder ) (ss []filedesc .Service , err error ) {
ss = make ([]filedesc .Service , len (sds ))
for i , sd := range sds {
s := &ss [i ]
s .L2 = new (filedesc .ServiceL2 )
if s .L0 , err = r .makeBase (s , parent , sd .GetName (), i , sb ); err != nil {
return nil , err
}
if opts := sd .GetOptions (); opts != nil {
opts = proto .Clone (opts ).(*descriptorpb .ServiceOptions )
s .L2 .Options = func () protoreflect .ProtoMessage { return opts }
}
if s .L2 .Methods .List , err = r .initMethodsFromDescriptorProto (sd .GetMethod (), s , sb ); err != nil {
return nil , err
}
}
return ss , nil
}
func (r descsByName ) initMethodsFromDescriptorProto (mds []*descriptorpb .MethodDescriptorProto , parent protoreflect .Descriptor , sb *strs .Builder ) (ms []filedesc .Method , err error ) {
ms = make ([]filedesc .Method , len (mds ))
for i , md := range mds {
m := &ms [i ]
if m .L0 , err = r .makeBase (m , parent , md .GetName (), i , sb ); err != nil {
return nil , err
}
if opts := md .GetOptions (); opts != nil {
opts = proto .Clone (opts ).(*descriptorpb .MethodOptions )
m .L1 .Options = func () protoreflect .ProtoMessage { return opts }
}
m .L1 .IsStreamingClient = md .GetClientStreaming ()
m .L1 .IsStreamingServer = md .GetServerStreaming ()
}
return ms , nil
}
func (r descsByName ) makeBase (child , parent protoreflect .Descriptor , name string , idx int , sb *strs .Builder ) (filedesc .BaseL0 , error ) {
if !protoreflect .Name (name ).IsValid () {
return filedesc .BaseL0 {}, errors .New ("descriptor %q has an invalid nested name: %q" , parent .FullName (), name )
}
var fullName protoreflect .FullName
if _ , ok := parent .(protoreflect .EnumDescriptor ); ok {
fullName = sb .AppendFullName (parent .FullName ().Parent (), protoreflect .Name (name ))
} else {
fullName = sb .AppendFullName (parent .FullName (), protoreflect .Name (name ))
}
if _ , ok := r [fullName ]; ok {
return filedesc .BaseL0 {}, errors .New ("descriptor %q already declared" , fullName )
}
r [fullName ] = child
return filedesc .BaseL0 {
FullName : fullName ,
ParentFile : parent .ParentFile ().(*filedesc .File ),
Parent : parent ,
Index : idx ,
}, nil
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .