github.com/whiteCcinn/protobuf-go@v1.0.9/internal/filedesc/desc.go (about)

     1  // Copyright 2019 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package filedesc
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"sync"
    11  	"sync/atomic"
    12  
    13  	"github.com/whiteCcinn/protobuf-go/internal/descfmt"
    14  	"github.com/whiteCcinn/protobuf-go/internal/descopts"
    15  	"github.com/whiteCcinn/protobuf-go/internal/encoding/defval"
    16  	"github.com/whiteCcinn/protobuf-go/internal/encoding/messageset"
    17  	"github.com/whiteCcinn/protobuf-go/internal/genid"
    18  	"github.com/whiteCcinn/protobuf-go/internal/pragma"
    19  	"github.com/whiteCcinn/protobuf-go/internal/strs"
    20  	"github.com/whiteCcinn/protobuf-go/reflect/protoreflect"
    21  	"github.com/whiteCcinn/protobuf-go/reflect/protoregistry"
    22  )
    23  
    24  // The types in this file may have a suffix:
    25  //	• L0: Contains fields common to all descriptors (except File) and
    26  //	must be initialized up front.
    27  //	• L1: Contains fields specific to a descriptor and
    28  //	must be initialized up front.
    29  //	• L2: Contains fields that are lazily initialized when constructing
    30  //	from the raw file descriptor. When constructing as a literal, the L2
    31  //	fields must be initialized up front.
    32  //
    33  // The types are exported so that packages like reflect/protodesc can
    34  // directly construct descriptors.
    35  
    36  type (
    37  	File struct {
    38  		fileRaw
    39  		L1 FileL1
    40  
    41  		once uint32     // atomically set if L2 is valid
    42  		mu   sync.Mutex // protects L2
    43  		L2   *FileL2
    44  	}
    45  	FileL1 struct {
    46  		Syntax  protoreflect.Syntax
    47  		Path    string
    48  		Package protoreflect.FullName
    49  
    50  		Enums      Enums
    51  		Messages   Messages
    52  		Extensions Extensions
    53  		Services   Services
    54  	}
    55  	FileL2 struct {
    56  		Options   func() protoreflect.ProtoMessage
    57  		Imports   FileImports
    58  		Locations SourceLocations
    59  	}
    60  )
    61  
    62  func (fd *File) ParentFile() protoreflect.FileDescriptor { return fd }
    63  func (fd *File) Parent() protoreflect.Descriptor         { return nil }
    64  func (fd *File) Index() int                              { return 0 }
    65  func (fd *File) Syntax() protoreflect.Syntax             { return fd.L1.Syntax }
    66  func (fd *File) Name() protoreflect.Name                 { return fd.L1.Package.Name() }
    67  func (fd *File) FullName() protoreflect.FullName         { return fd.L1.Package }
    68  func (fd *File) IsPlaceholder() bool                     { return false }
    69  func (fd *File) Options() protoreflect.ProtoMessage {
    70  	if f := fd.lazyInit().Options; f != nil {
    71  		return f()
    72  	}
    73  	return descopts.File
    74  }
    75  func (fd *File) Path() string                                  { return fd.L1.Path }
    76  func (fd *File) Package() protoreflect.FullName                { return fd.L1.Package }
    77  func (fd *File) Imports() protoreflect.FileImports             { return &fd.lazyInit().Imports }
    78  func (fd *File) Enums() protoreflect.EnumDescriptors           { return &fd.L1.Enums }
    79  func (fd *File) Messages() protoreflect.MessageDescriptors     { return &fd.L1.Messages }
    80  func (fd *File) Extensions() protoreflect.ExtensionDescriptors { return &fd.L1.Extensions }
    81  func (fd *File) Services() protoreflect.ServiceDescriptors     { return &fd.L1.Services }
    82  func (fd *File) SourceLocations() protoreflect.SourceLocations { return &fd.lazyInit().Locations }
    83  func (fd *File) Format(s fmt.State, r rune)                    { descfmt.FormatDesc(s, r, fd) }
    84  func (fd *File) ProtoType(protoreflect.FileDescriptor)         {}
    85  func (fd *File) ProtoInternal(pragma.DoNotImplement)           {}
    86  
    87  func (fd *File) lazyInit() *FileL2 {
    88  	if atomic.LoadUint32(&fd.once) == 0 {
    89  		fd.lazyInitOnce()
    90  	}
    91  	return fd.L2
    92  }
    93  
    94  func (fd *File) lazyInitOnce() {
    95  	fd.mu.Lock()
    96  	if fd.L2 == nil {
    97  		fd.lazyRawInit() // recursively initializes all L2 structures
    98  	}
    99  	atomic.StoreUint32(&fd.once, 1)
   100  	fd.mu.Unlock()
   101  }
   102  
   103  // GoPackagePath is a pseudo-internal API for determining the Go package path
   104  // that this file descriptor is declared in.
   105  //
   106  // WARNING: This method is exempt from the compatibility promise and may be
   107  // removed in the future without warning.
   108  func (fd *File) GoPackagePath() string {
   109  	return fd.builder.GoPackagePath
   110  }
   111  
   112  type (
   113  	Enum struct {
   114  		Base
   115  		L1 EnumL1
   116  		L2 *EnumL2 // protected by fileDesc.once
   117  	}
   118  	EnumL1 struct {
   119  		eagerValues bool // controls whether EnumL2.Values is already populated
   120  	}
   121  	EnumL2 struct {
   122  		Options        func() protoreflect.ProtoMessage
   123  		Values         EnumValues
   124  		ReservedNames  Names
   125  		ReservedRanges EnumRanges
   126  	}
   127  
   128  	EnumValue struct {
   129  		Base
   130  		L1 EnumValueL1
   131  	}
   132  	EnumValueL1 struct {
   133  		Options func() protoreflect.ProtoMessage
   134  		Number  protoreflect.EnumNumber
   135  	}
   136  )
   137  
   138  func (ed *Enum) Options() protoreflect.ProtoMessage {
   139  	if f := ed.lazyInit().Options; f != nil {
   140  		return f()
   141  	}
   142  	return descopts.Enum
   143  }
   144  func (ed *Enum) Values() protoreflect.EnumValueDescriptors {
   145  	if ed.L1.eagerValues {
   146  		return &ed.L2.Values
   147  	}
   148  	return &ed.lazyInit().Values
   149  }
   150  func (ed *Enum) ReservedNames() protoreflect.Names       { return &ed.lazyInit().ReservedNames }
   151  func (ed *Enum) ReservedRanges() protoreflect.EnumRanges { return &ed.lazyInit().ReservedRanges }
   152  func (ed *Enum) Format(s fmt.State, r rune)              { descfmt.FormatDesc(s, r, ed) }
   153  func (ed *Enum) ProtoType(protoreflect.EnumDescriptor)   {}
   154  func (ed *Enum) lazyInit() *EnumL2 {
   155  	ed.L0.ParentFile.lazyInit() // implicitly initializes L2
   156  	return ed.L2
   157  }
   158  
   159  func (ed *EnumValue) Options() protoreflect.ProtoMessage {
   160  	if f := ed.L1.Options; f != nil {
   161  		return f()
   162  	}
   163  	return descopts.EnumValue
   164  }
   165  func (ed *EnumValue) Number() protoreflect.EnumNumber            { return ed.L1.Number }
   166  func (ed *EnumValue) Format(s fmt.State, r rune)                 { descfmt.FormatDesc(s, r, ed) }
   167  func (ed *EnumValue) ProtoType(protoreflect.EnumValueDescriptor) {}
   168  
   169  type (
   170  	Message struct {
   171  		Base
   172  		L1 MessageL1
   173  		L2 *MessageL2 // protected by fileDesc.once
   174  	}
   175  	MessageL1 struct {
   176  		Enums        Enums
   177  		Messages     Messages
   178  		Extensions   Extensions
   179  		IsMapEntry   bool // promoted from google.protobuf.MessageOptions
   180  		IsMessageSet bool // promoted from google.protobuf.MessageOptions
   181  	}
   182  	MessageL2 struct {
   183  		Options               func() protoreflect.ProtoMessage
   184  		Fields                Fields
   185  		Oneofs                Oneofs
   186  		ReservedNames         Names
   187  		ReservedRanges        FieldRanges
   188  		RequiredNumbers       FieldNumbers // must be consistent with Fields.Cardinality
   189  		ExtensionRanges       FieldRanges
   190  		ExtensionRangeOptions []func() protoreflect.ProtoMessage // must be same length as ExtensionRanges
   191  	}
   192  
   193  	Field struct {
   194  		Base
   195  		L1 FieldL1
   196  	}
   197  	FieldL1 struct {
   198  		Options          func() protoreflect.ProtoMessage
   199  		Number           protoreflect.FieldNumber
   200  		Cardinality      protoreflect.Cardinality // must be consistent with Message.RequiredNumbers
   201  		Kind             protoreflect.Kind
   202  		StringName       stringName
   203  		IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto
   204  		IsWeak           bool // promoted from google.protobuf.FieldOptions
   205  		HasPacked        bool // promoted from google.protobuf.FieldOptions
   206  		IsPacked         bool // promoted from google.protobuf.FieldOptions
   207  		HasEnforceUTF8   bool // promoted from google.protobuf.FieldOptions
   208  		EnforceUTF8      bool // promoted from google.protobuf.FieldOptions
   209  		Default          defaultValue
   210  		ContainingOneof  protoreflect.OneofDescriptor // must be consistent with Message.Oneofs.Fields
   211  		Enum             protoreflect.EnumDescriptor
   212  		Message          protoreflect.MessageDescriptor
   213  	}
   214  
   215  	Oneof struct {
   216  		Base
   217  		L1 OneofL1
   218  	}
   219  	OneofL1 struct {
   220  		Options func() protoreflect.ProtoMessage
   221  		Fields  OneofFields // must be consistent with Message.Fields.ContainingOneof
   222  	}
   223  )
   224  
   225  func (md *Message) Options() protoreflect.ProtoMessage {
   226  	if f := md.lazyInit().Options; f != nil {
   227  		return f()
   228  	}
   229  	return descopts.Message
   230  }
   231  func (md *Message) IsMapEntry() bool                           { return md.L1.IsMapEntry }
   232  func (md *Message) Fields() protoreflect.FieldDescriptors      { return &md.lazyInit().Fields }
   233  func (md *Message) Oneofs() protoreflect.OneofDescriptors      { return &md.lazyInit().Oneofs }
   234  func (md *Message) ReservedNames() protoreflect.Names          { return &md.lazyInit().ReservedNames }
   235  func (md *Message) ReservedRanges() protoreflect.FieldRanges   { return &md.lazyInit().ReservedRanges }
   236  func (md *Message) RequiredNumbers() protoreflect.FieldNumbers { return &md.lazyInit().RequiredNumbers }
   237  func (md *Message) ExtensionRanges() protoreflect.FieldRanges  { return &md.lazyInit().ExtensionRanges }
   238  func (md *Message) ExtensionRangeOptions(i int) protoreflect.ProtoMessage {
   239  	if f := md.lazyInit().ExtensionRangeOptions[i]; f != nil {
   240  		return f()
   241  	}
   242  	return descopts.ExtensionRange
   243  }
   244  func (md *Message) Enums() protoreflect.EnumDescriptors           { return &md.L1.Enums }
   245  func (md *Message) Messages() protoreflect.MessageDescriptors     { return &md.L1.Messages }
   246  func (md *Message) Extensions() protoreflect.ExtensionDescriptors { return &md.L1.Extensions }
   247  func (md *Message) ProtoType(protoreflect.MessageDescriptor)      {}
   248  func (md *Message) Format(s fmt.State, r rune)                    { descfmt.FormatDesc(s, r, md) }
   249  func (md *Message) lazyInit() *MessageL2 {
   250  	md.L0.ParentFile.lazyInit() // implicitly initializes L2
   251  	return md.L2
   252  }
   253  
   254  // IsMessageSet is a pseudo-internal API for checking whether a message
   255  // should serialize in the proto1 message format.
   256  //
   257  // WARNING: This method is exempt from the compatibility promise and may be
   258  // removed in the future without warning.
   259  func (md *Message) IsMessageSet() bool {
   260  	return md.L1.IsMessageSet
   261  }
   262  
   263  func (fd *Field) Options() protoreflect.ProtoMessage {
   264  	if f := fd.L1.Options; f != nil {
   265  		return f()
   266  	}
   267  	return descopts.Field
   268  }
   269  func (fd *Field) Number() protoreflect.FieldNumber      { return fd.L1.Number }
   270  func (fd *Field) Cardinality() protoreflect.Cardinality { return fd.L1.Cardinality }
   271  func (fd *Field) Kind() protoreflect.Kind               { return fd.L1.Kind }
   272  func (fd *Field) HasJSONName() bool                     { return fd.L1.StringName.hasJSON }
   273  func (fd *Field) JSONName() string                      { return fd.L1.StringName.getJSON(fd) }
   274  func (fd *Field) TextName() string                      { return fd.L1.StringName.getText(fd) }
   275  func (fd *Field) HasPresence() bool {
   276  	return fd.L1.Cardinality != protoreflect.Repeated && (fd.L0.ParentFile.L1.Syntax == protoreflect.Proto2 || fd.L1.Message != nil || fd.L1.ContainingOneof != nil)
   277  }
   278  func (fd *Field) HasOptionalKeyword() bool {
   279  	return (fd.L0.ParentFile.L1.Syntax == protoreflect.Proto2 && fd.L1.Cardinality == protoreflect.Optional && fd.L1.ContainingOneof == nil) || fd.L1.IsProto3Optional
   280  }
   281  func (fd *Field) IsPacked() bool {
   282  	if !fd.L1.HasPacked && fd.L0.ParentFile.L1.Syntax != protoreflect.Proto2 && fd.L1.Cardinality == protoreflect.Repeated {
   283  		switch fd.L1.Kind {
   284  		case protoreflect.StringKind, protoreflect.BytesKind, protoreflect.MessageKind, protoreflect.GroupKind:
   285  		default:
   286  			return true
   287  		}
   288  	}
   289  	return fd.L1.IsPacked
   290  }
   291  func (fd *Field) IsExtension() bool { return false }
   292  func (fd *Field) IsWeak() bool      { return fd.L1.IsWeak }
   293  func (fd *Field) IsList() bool      { return fd.Cardinality() == protoreflect.Repeated && !fd.IsMap() }
   294  func (fd *Field) IsMap() bool       { return fd.Message() != nil && fd.Message().IsMapEntry() }
   295  func (fd *Field) MapKey() protoreflect.FieldDescriptor {
   296  	if !fd.IsMap() {
   297  		return nil
   298  	}
   299  	return fd.Message().Fields().ByNumber(genid.MapEntry_Key_field_number)
   300  }
   301  func (fd *Field) MapValue() protoreflect.FieldDescriptor {
   302  	if !fd.IsMap() {
   303  		return nil
   304  	}
   305  	return fd.Message().Fields().ByNumber(genid.MapEntry_Value_field_number)
   306  }
   307  func (fd *Field) HasDefault() bool                                   { return fd.L1.Default.has }
   308  func (fd *Field) Default() protoreflect.Value                        { return fd.L1.Default.get(fd) }
   309  func (fd *Field) DefaultEnumValue() protoreflect.EnumValueDescriptor { return fd.L1.Default.enum }
   310  func (fd *Field) ContainingOneof() protoreflect.OneofDescriptor      { return fd.L1.ContainingOneof }
   311  func (fd *Field) ContainingMessage() protoreflect.MessageDescriptor {
   312  	return fd.L0.Parent.(protoreflect.MessageDescriptor)
   313  }
   314  func (fd *Field) Enum() protoreflect.EnumDescriptor {
   315  	return fd.L1.Enum
   316  }
   317  func (fd *Field) Message() protoreflect.MessageDescriptor {
   318  	if fd.L1.IsWeak {
   319  		if d, _ := protoregistry.GlobalFiles.FindDescriptorByName(fd.L1.Message.FullName()); d != nil {
   320  			return d.(protoreflect.MessageDescriptor)
   321  		}
   322  	}
   323  	return fd.L1.Message
   324  }
   325  func (fd *Field) Format(s fmt.State, r rune)             { descfmt.FormatDesc(s, r, fd) }
   326  func (fd *Field) ProtoType(protoreflect.FieldDescriptor) {}
   327  
   328  // EnforceUTF8 is a pseudo-internal API to determine whether to enforce UTF-8
   329  // validation for the string field. This exists for Google-internal use only
   330  // since proto3 did not enforce UTF-8 validity prior to the open-source release.
   331  // If this method does not exist, the default is to enforce valid UTF-8.
   332  //
   333  // WARNING: This method is exempt from the compatibility promise and may be
   334  // removed in the future without warning.
   335  func (fd *Field) EnforceUTF8() bool {
   336  	if fd.L1.HasEnforceUTF8 {
   337  		return fd.L1.EnforceUTF8
   338  	}
   339  	return fd.L0.ParentFile.L1.Syntax == protoreflect.Proto3
   340  }
   341  
   342  func (od *Oneof) IsSynthetic() bool {
   343  	return od.L0.ParentFile.L1.Syntax == protoreflect.Proto3 && len(od.L1.Fields.List) == 1 && od.L1.Fields.List[0].HasOptionalKeyword()
   344  }
   345  func (od *Oneof) Options() protoreflect.ProtoMessage {
   346  	if f := od.L1.Options; f != nil {
   347  		return f()
   348  	}
   349  	return descopts.Oneof
   350  }
   351  func (od *Oneof) Fields() protoreflect.FieldDescriptors  { return &od.L1.Fields }
   352  func (od *Oneof) Format(s fmt.State, r rune)             { descfmt.FormatDesc(s, r, od) }
   353  func (od *Oneof) ProtoType(protoreflect.OneofDescriptor) {}
   354  
   355  type (
   356  	Extension struct {
   357  		Base
   358  		L1 ExtensionL1
   359  		L2 *ExtensionL2 // protected by fileDesc.once
   360  	}
   361  	ExtensionL1 struct {
   362  		Number      protoreflect.FieldNumber
   363  		Extendee    protoreflect.MessageDescriptor
   364  		Cardinality protoreflect.Cardinality
   365  		Kind        protoreflect.Kind
   366  	}
   367  	ExtensionL2 struct {
   368  		Options          func() protoreflect.ProtoMessage
   369  		StringName       stringName
   370  		IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto
   371  		IsPacked         bool // promoted from google.protobuf.FieldOptions
   372  		Default          defaultValue
   373  		Enum             protoreflect.EnumDescriptor
   374  		Message          protoreflect.MessageDescriptor
   375  	}
   376  )
   377  
   378  func (xd *Extension) Options() protoreflect.ProtoMessage {
   379  	if f := xd.lazyInit().Options; f != nil {
   380  		return f()
   381  	}
   382  	return descopts.Field
   383  }
   384  func (xd *Extension) Number() protoreflect.FieldNumber      { return xd.L1.Number }
   385  func (xd *Extension) Cardinality() protoreflect.Cardinality { return xd.L1.Cardinality }
   386  func (xd *Extension) Kind() protoreflect.Kind               { return xd.L1.Kind }
   387  func (xd *Extension) HasJSONName() bool                     { return xd.lazyInit().StringName.hasJSON }
   388  func (xd *Extension) JSONName() string                      { return xd.lazyInit().StringName.getJSON(xd) }
   389  func (xd *Extension) TextName() string                      { return xd.lazyInit().StringName.getText(xd) }
   390  func (xd *Extension) HasPresence() bool                     { return xd.L1.Cardinality != protoreflect.Repeated }
   391  func (xd *Extension) HasOptionalKeyword() bool {
   392  	return (xd.L0.ParentFile.L1.Syntax == protoreflect.Proto2 && xd.L1.Cardinality == protoreflect.Optional) || xd.lazyInit().IsProto3Optional
   393  }
   394  func (xd *Extension) IsPacked() bool                         { return xd.lazyInit().IsPacked }
   395  func (xd *Extension) IsExtension() bool                      { return true }
   396  func (xd *Extension) IsWeak() bool                           { return false }
   397  func (xd *Extension) IsList() bool                           { return xd.Cardinality() == protoreflect.Repeated }
   398  func (xd *Extension) IsMap() bool                            { return false }
   399  func (xd *Extension) MapKey() protoreflect.FieldDescriptor   { return nil }
   400  func (xd *Extension) MapValue() protoreflect.FieldDescriptor { return nil }
   401  func (xd *Extension) HasDefault() bool                       { return xd.lazyInit().Default.has }
   402  func (xd *Extension) Default() protoreflect.Value            { return xd.lazyInit().Default.get(xd) }
   403  func (xd *Extension) DefaultEnumValue() protoreflect.EnumValueDescriptor {
   404  	return xd.lazyInit().Default.enum
   405  }
   406  func (xd *Extension) ContainingOneof() protoreflect.OneofDescriptor     { return nil }
   407  func (xd *Extension) ContainingMessage() protoreflect.MessageDescriptor { return xd.L1.Extendee }
   408  func (xd *Extension) Enum() protoreflect.EnumDescriptor                 { return xd.lazyInit().Enum }
   409  func (xd *Extension) Message() protoreflect.MessageDescriptor           { return xd.lazyInit().Message }
   410  func (xd *Extension) Format(s fmt.State, r rune)                        { descfmt.FormatDesc(s, r, xd) }
   411  func (xd *Extension) ProtoType(protoreflect.FieldDescriptor)            {}
   412  func (xd *Extension) ProtoInternal(pragma.DoNotImplement)               {}
   413  func (xd *Extension) lazyInit() *ExtensionL2 {
   414  	xd.L0.ParentFile.lazyInit() // implicitly initializes L2
   415  	return xd.L2
   416  }
   417  
   418  type (
   419  	Service struct {
   420  		Base
   421  		L1 ServiceL1
   422  		L2 *ServiceL2 // protected by fileDesc.once
   423  	}
   424  	ServiceL1 struct{}
   425  	ServiceL2 struct {
   426  		Options func() protoreflect.ProtoMessage
   427  		Methods Methods
   428  	}
   429  
   430  	Method struct {
   431  		Base
   432  		L1 MethodL1
   433  	}
   434  	MethodL1 struct {
   435  		Options           func() protoreflect.ProtoMessage
   436  		Input             protoreflect.MessageDescriptor
   437  		Output            protoreflect.MessageDescriptor
   438  		IsStreamingClient bool
   439  		IsStreamingServer bool
   440  	}
   441  )
   442  
   443  func (sd *Service) Options() protoreflect.ProtoMessage {
   444  	if f := sd.lazyInit().Options; f != nil {
   445  		return f()
   446  	}
   447  	return descopts.Service
   448  }
   449  func (sd *Service) Methods() protoreflect.MethodDescriptors  { return &sd.lazyInit().Methods }
   450  func (sd *Service) Format(s fmt.State, r rune)               { descfmt.FormatDesc(s, r, sd) }
   451  func (sd *Service) ProtoType(protoreflect.ServiceDescriptor) {}
   452  func (sd *Service) ProtoInternal(pragma.DoNotImplement)      {}
   453  func (sd *Service) lazyInit() *ServiceL2 {
   454  	sd.L0.ParentFile.lazyInit() // implicitly initializes L2
   455  	return sd.L2
   456  }
   457  
   458  func (md *Method) Options() protoreflect.ProtoMessage {
   459  	if f := md.L1.Options; f != nil {
   460  		return f()
   461  	}
   462  	return descopts.Method
   463  }
   464  func (md *Method) Input() protoreflect.MessageDescriptor   { return md.L1.Input }
   465  func (md *Method) Output() protoreflect.MessageDescriptor  { return md.L1.Output }
   466  func (md *Method) IsStreamingClient() bool                 { return md.L1.IsStreamingClient }
   467  func (md *Method) IsStreamingServer() bool                 { return md.L1.IsStreamingServer }
   468  func (md *Method) Format(s fmt.State, r rune)              { descfmt.FormatDesc(s, r, md) }
   469  func (md *Method) ProtoType(protoreflect.MethodDescriptor) {}
   470  func (md *Method) ProtoInternal(pragma.DoNotImplement)     {}
   471  
   472  // Surrogate files are can be used to create standalone descriptors
   473  // where the syntax is only information derived from the parent file.
   474  var (
   475  	SurrogateProto2 = &File{L1: FileL1{Syntax: protoreflect.Proto2}, L2: &FileL2{}}
   476  	SurrogateProto3 = &File{L1: FileL1{Syntax: protoreflect.Proto3}, L2: &FileL2{}}
   477  )
   478  
   479  type (
   480  	Base struct {
   481  		L0 BaseL0
   482  	}
   483  	BaseL0 struct {
   484  		FullName   protoreflect.FullName // must be populated
   485  		ParentFile *File                 // must be populated
   486  		Parent     protoreflect.Descriptor
   487  		Index      int
   488  	}
   489  )
   490  
   491  func (d *Base) Name() protoreflect.Name         { return d.L0.FullName.Name() }
   492  func (d *Base) FullName() protoreflect.FullName { return d.L0.FullName }
   493  func (d *Base) ParentFile() protoreflect.FileDescriptor {
   494  	if d.L0.ParentFile == SurrogateProto2 || d.L0.ParentFile == SurrogateProto3 {
   495  		return nil // surrogate files are not real parents
   496  	}
   497  	return d.L0.ParentFile
   498  }
   499  func (d *Base) Parent() protoreflect.Descriptor     { return d.L0.Parent }
   500  func (d *Base) Index() int                          { return d.L0.Index }
   501  func (d *Base) Syntax() protoreflect.Syntax         { return d.L0.ParentFile.Syntax() }
   502  func (d *Base) IsPlaceholder() bool                 { return false }
   503  func (d *Base) ProtoInternal(pragma.DoNotImplement) {}
   504  
   505  type stringName struct {
   506  	hasJSON  bool
   507  	once     sync.Once
   508  	nameJSON string
   509  	nameText string
   510  }
   511  
   512  // InitJSON initializes the name. It is exported for use by other internal packages.
   513  func (s *stringName) InitJSON(name string) {
   514  	s.hasJSON = true
   515  	s.nameJSON = name
   516  }
   517  
   518  func (s *stringName) lazyInit(fd protoreflect.FieldDescriptor) *stringName {
   519  	s.once.Do(func() {
   520  		if fd.IsExtension() {
   521  			// For extensions, JSON and text are formatted the same way.
   522  			var name string
   523  			if messageset.IsMessageSetExtension(fd) {
   524  				name = string("[" + fd.FullName().Parent() + "]")
   525  			} else {
   526  				name = string("[" + fd.FullName() + "]")
   527  			}
   528  			s.nameJSON = name
   529  			s.nameText = name
   530  		} else {
   531  			// Format the JSON name.
   532  			if !s.hasJSON {
   533  				s.nameJSON = strs.JSONCamelCase(string(fd.Name()))
   534  			}
   535  
   536  			// Format the text name.
   537  			s.nameText = string(fd.Name())
   538  			if fd.Kind() == protoreflect.GroupKind {
   539  				s.nameText = string(fd.Message().Name())
   540  			}
   541  		}
   542  	})
   543  	return s
   544  }
   545  
   546  func (s *stringName) getJSON(fd protoreflect.FieldDescriptor) string { return s.lazyInit(fd).nameJSON }
   547  func (s *stringName) getText(fd protoreflect.FieldDescriptor) string { return s.lazyInit(fd).nameText }
   548  
   549  func DefaultValue(v protoreflect.Value, ev protoreflect.EnumValueDescriptor) defaultValue {
   550  	dv := defaultValue{has: v.IsValid(), val: v, enum: ev}
   551  	if b, ok := v.Interface().([]byte); ok {
   552  		// Store a copy of the default bytes, so that we can detect
   553  		// accidental mutations of the original value.
   554  		dv.bytes = append([]byte(nil), b...)
   555  	}
   556  	return dv
   557  }
   558  
   559  func unmarshalDefault(b []byte, k protoreflect.Kind, pf *File, ed protoreflect.EnumDescriptor) defaultValue {
   560  	var evs protoreflect.EnumValueDescriptors
   561  	if k == protoreflect.EnumKind {
   562  		// If the enum is declared within the same file, be careful not to
   563  		// blindly call the Values method, lest we bind ourselves in a deadlock.
   564  		if e, ok := ed.(*Enum); ok && e.L0.ParentFile == pf {
   565  			evs = &e.L2.Values
   566  		} else {
   567  			evs = ed.Values()
   568  		}
   569  
   570  		// If we are unable to resolve the enum dependency, use a placeholder
   571  		// enum value since we will not be able to parse the default value.
   572  		if ed.IsPlaceholder() && protoreflect.Name(b).IsValid() {
   573  			v := protoreflect.ValueOfEnum(0)
   574  			ev := PlaceholderEnumValue(ed.FullName().Parent().Append(protoreflect.Name(b)))
   575  			return DefaultValue(v, ev)
   576  		}
   577  	}
   578  
   579  	v, ev, err := defval.Unmarshal(string(b), k, evs, defval.Descriptor)
   580  	if err != nil {
   581  		panic(err)
   582  	}
   583  	return DefaultValue(v, ev)
   584  }
   585  
   586  type defaultValue struct {
   587  	has   bool
   588  	val   protoreflect.Value
   589  	enum  protoreflect.EnumValueDescriptor
   590  	bytes []byte
   591  }
   592  
   593  func (dv *defaultValue) get(fd protoreflect.FieldDescriptor) protoreflect.Value {
   594  	// Return the zero value as the default if unpopulated.
   595  	if !dv.has {
   596  		if fd.Cardinality() == protoreflect.Repeated {
   597  			return protoreflect.Value{}
   598  		}
   599  		switch fd.Kind() {
   600  		case protoreflect.BoolKind:
   601  			return protoreflect.ValueOfBool(false)
   602  		case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
   603  			return protoreflect.ValueOfInt32(0)
   604  		case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
   605  			return protoreflect.ValueOfInt64(0)
   606  		case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
   607  			return protoreflect.ValueOfUint32(0)
   608  		case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
   609  			return protoreflect.ValueOfUint64(0)
   610  		case protoreflect.FloatKind:
   611  			return protoreflect.ValueOfFloat32(0)
   612  		case protoreflect.DoubleKind:
   613  			return protoreflect.ValueOfFloat64(0)
   614  		case protoreflect.StringKind:
   615  			return protoreflect.ValueOfString("")
   616  		case protoreflect.BytesKind:
   617  			return protoreflect.ValueOfBytes(nil)
   618  		case protoreflect.EnumKind:
   619  			if evs := fd.Enum().Values(); evs.Len() > 0 {
   620  				return protoreflect.ValueOfEnum(evs.Get(0).Number())
   621  			}
   622  			return protoreflect.ValueOfEnum(0)
   623  		}
   624  	}
   625  
   626  	if len(dv.bytes) > 0 && !bytes.Equal(dv.bytes, dv.val.Bytes()) {
   627  		// TODO: Avoid panic if we're running with the race detector
   628  		// and instead spawn a goroutine that periodically resets
   629  		// this value back to the original to induce a race.
   630  		panic(fmt.Sprintf("detected mutation on the default bytes for %v", fd.FullName()))
   631  	}
   632  	return dv.val
   633  }