desc.go raw

   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  	"strings"
  11  	"sync"
  12  	"sync/atomic"
  13  
  14  	"google.golang.org/protobuf/internal/descfmt"
  15  	"google.golang.org/protobuf/internal/descopts"
  16  	"google.golang.org/protobuf/internal/encoding/defval"
  17  	"google.golang.org/protobuf/internal/encoding/messageset"
  18  	"google.golang.org/protobuf/internal/genid"
  19  	"google.golang.org/protobuf/internal/pragma"
  20  	"google.golang.org/protobuf/internal/strs"
  21  	"google.golang.org/protobuf/reflect/protoreflect"
  22  )
  23  
  24  // Edition is an Enum for proto2.Edition
  25  type Edition int32
  26  
  27  // These values align with the value of Enum in descriptor.proto which allows
  28  // direct conversion between the proto enum and this enum.
  29  const (
  30  	EditionUnknown     Edition = 0
  31  	EditionProto2      Edition = 998
  32  	EditionProto3      Edition = 999
  33  	Edition2023        Edition = 1000
  34  	Edition2024        Edition = 1001
  35  	EditionUnstable    Edition = 9999
  36  	EditionUnsupported Edition = 100000
  37  )
  38  
  39  // The types in this file may have a suffix:
  40  //	• L0: Contains fields common to all descriptors (except File) and
  41  //	must be initialized up front.
  42  //	• L1: Contains fields specific to a descriptor and
  43  //	must be initialized up front. If the associated proto uses Editions, the
  44  //  Editions features must always be resolved. If not explicitly set, the
  45  //  appropriate default must be resolved and set.
  46  //	• L2: Contains fields that are lazily initialized when constructing
  47  //	from the raw file descriptor. When constructing as a literal, the L2
  48  //	fields must be initialized up front.
  49  //
  50  // The types are exported so that packages like reflect/protodesc can
  51  // directly construct descriptors.
  52  
  53  type (
  54  	File struct {
  55  		fileRaw
  56  		L1 FileL1
  57  
  58  		once uint32     // atomically set if L2 is valid
  59  		mu   sync.Mutex // protects L2
  60  		L2   *FileL2
  61  	}
  62  	FileL1 struct {
  63  		Syntax  protoreflect.Syntax
  64  		Edition Edition // Only used if Syntax == Editions
  65  		Path    string
  66  		Package protoreflect.FullName
  67  
  68  		Enums      Enums
  69  		Messages   Messages
  70  		Extensions Extensions
  71  		Services   Services
  72  
  73  		EditionFeatures EditionFeatures
  74  	}
  75  	FileL2 struct {
  76  		Options       func() protoreflect.ProtoMessage
  77  		Imports       FileImports
  78  		OptionImports func() protoreflect.FileImports
  79  		Locations     SourceLocations
  80  	}
  81  
  82  	// EditionFeatures is a frequently-instantiated struct, so please take care
  83  	// to minimize padding when adding new fields to this struct (add them in
  84  	// the right place/order).
  85  	EditionFeatures struct {
  86  		// StripEnumPrefix determines if the plugin generates enum value
  87  		// constants as-is, with their prefix stripped, or both variants.
  88  		StripEnumPrefix int
  89  
  90  		// IsFieldPresence is true if field_presence is EXPLICIT
  91  		// https://protobuf.dev/editions/features/#field_presence
  92  		IsFieldPresence bool
  93  
  94  		// IsFieldPresence is true if field_presence is LEGACY_REQUIRED
  95  		// https://protobuf.dev/editions/features/#field_presence
  96  		IsLegacyRequired bool
  97  
  98  		// IsOpenEnum is true if enum_type is OPEN
  99  		// https://protobuf.dev/editions/features/#enum_type
 100  		IsOpenEnum bool
 101  
 102  		// IsPacked is true if repeated_field_encoding is PACKED
 103  		// https://protobuf.dev/editions/features/#repeated_field_encoding
 104  		IsPacked bool
 105  
 106  		// IsUTF8Validated is true if utf_validation is VERIFY
 107  		// https://protobuf.dev/editions/features/#utf8_validation
 108  		IsUTF8Validated bool
 109  
 110  		// IsDelimitedEncoded is true if message_encoding is DELIMITED
 111  		// https://protobuf.dev/editions/features/#message_encoding
 112  		IsDelimitedEncoded bool
 113  
 114  		// IsJSONCompliant is true if json_format is ALLOW
 115  		// https://protobuf.dev/editions/features/#json_format
 116  		IsJSONCompliant bool
 117  
 118  		// GenerateLegacyUnmarshalJSON determines if the plugin generates the
 119  		// UnmarshalJSON([]byte) error method for enums.
 120  		GenerateLegacyUnmarshalJSON bool
 121  		// APILevel controls which API (Open, Hybrid or Opaque) should be used
 122  		// for generated code (.pb.go files).
 123  		APILevel int
 124  	}
 125  )
 126  
 127  func (fd *File) ParentFile() protoreflect.FileDescriptor { return fd }
 128  func (fd *File) Parent() protoreflect.Descriptor         { return nil }
 129  func (fd *File) Index() int                              { return 0 }
 130  func (fd *File) Syntax() protoreflect.Syntax             { return fd.L1.Syntax }
 131  func (fd *File) Name() protoreflect.Name                 { return fd.L1.Package.Name() }
 132  func (fd *File) FullName() protoreflect.FullName         { return fd.L1.Package }
 133  func (fd *File) IsPlaceholder() bool                     { return false }
 134  func (fd *File) Options() protoreflect.ProtoMessage {
 135  	if f := fd.lazyInit().Options; f != nil {
 136  		return f()
 137  	}
 138  	return descopts.File
 139  }
 140  func (fd *File) Path() string                                  { return fd.L1.Path }
 141  func (fd *File) Package() protoreflect.FullName                { return fd.L1.Package }
 142  func (fd *File) Imports() protoreflect.FileImports             { return &fd.lazyInit().Imports }
 143  func (fd *File) Enums() protoreflect.EnumDescriptors           { return &fd.L1.Enums }
 144  func (fd *File) Messages() protoreflect.MessageDescriptors     { return &fd.L1.Messages }
 145  func (fd *File) Extensions() protoreflect.ExtensionDescriptors { return &fd.L1.Extensions }
 146  func (fd *File) Services() protoreflect.ServiceDescriptors     { return &fd.L1.Services }
 147  func (fd *File) SourceLocations() protoreflect.SourceLocations { return &fd.lazyInit().Locations }
 148  func (fd *File) Format(s fmt.State, r rune)                    { descfmt.FormatDesc(s, r, fd) }
 149  func (fd *File) ProtoType(protoreflect.FileDescriptor)         {}
 150  func (fd *File) ProtoInternal(pragma.DoNotImplement)           {}
 151  
 152  // The next two are not part of the FileDescriptor interface. They are just used to reconstruct
 153  // the original FileDescriptor proto.
 154  func (fd *File) Edition() int32 { return int32(fd.L1.Edition) }
 155  func (fd *File) OptionImports() protoreflect.FileImports {
 156  	if f := fd.lazyInit().OptionImports; f != nil {
 157  		return f()
 158  	}
 159  	return emptyFiles
 160  }
 161  
 162  func (fd *File) lazyInit() *FileL2 {
 163  	if atomic.LoadUint32(&fd.once) == 0 {
 164  		fd.lazyInitOnce()
 165  	}
 166  	return fd.L2
 167  }
 168  
 169  func (fd *File) lazyInitOnce() {
 170  	fd.mu.Lock()
 171  	if fd.L2 == nil {
 172  		fd.lazyRawInit() // recursively initializes all L2 structures
 173  	}
 174  	atomic.StoreUint32(&fd.once, 1)
 175  	fd.mu.Unlock()
 176  }
 177  
 178  // GoPackagePath is a pseudo-internal API for determining the Go package path
 179  // that this file descriptor is declared in.
 180  //
 181  // WARNING: This method is exempt from the compatibility promise and may be
 182  // removed in the future without warning.
 183  func (fd *File) GoPackagePath() string {
 184  	return fd.builder.GoPackagePath
 185  }
 186  
 187  type (
 188  	Enum struct {
 189  		Base
 190  		L1 EnumL1
 191  		L2 *EnumL2 // protected by fileDesc.once
 192  	}
 193  	EnumL1 struct {
 194  		EditionFeatures EditionFeatures
 195  		Visibility      int32
 196  		eagerValues     bool // controls whether EnumL2.Values is already populated
 197  	}
 198  	EnumL2 struct {
 199  		Options        func() protoreflect.ProtoMessage
 200  		Values         EnumValues
 201  		ReservedNames  Names
 202  		ReservedRanges EnumRanges
 203  	}
 204  
 205  	EnumValue struct {
 206  		Base
 207  		L1 EnumValueL1
 208  	}
 209  	EnumValueL1 struct {
 210  		Options func() protoreflect.ProtoMessage
 211  		Number  protoreflect.EnumNumber
 212  	}
 213  )
 214  
 215  func (ed *Enum) Options() protoreflect.ProtoMessage {
 216  	if f := ed.lazyInit().Options; f != nil {
 217  		return f()
 218  	}
 219  	return descopts.Enum
 220  }
 221  func (ed *Enum) Values() protoreflect.EnumValueDescriptors {
 222  	if ed.L1.eagerValues {
 223  		return &ed.L2.Values
 224  	}
 225  	return &ed.lazyInit().Values
 226  }
 227  func (ed *Enum) ReservedNames() protoreflect.Names       { return &ed.lazyInit().ReservedNames }
 228  func (ed *Enum) ReservedRanges() protoreflect.EnumRanges { return &ed.lazyInit().ReservedRanges }
 229  func (ed *Enum) Format(s fmt.State, r rune)              { descfmt.FormatDesc(s, r, ed) }
 230  func (ed *Enum) ProtoType(protoreflect.EnumDescriptor)   {}
 231  
 232  // This is not part of the EnumDescriptor interface. It is just used to reconstruct
 233  // the original FileDescriptor proto.
 234  func (ed *Enum) Visibility() int32 { return ed.L1.Visibility }
 235  
 236  func (ed *Enum) lazyInit() *EnumL2 {
 237  	ed.L0.ParentFile.lazyInit() // implicitly initializes L2
 238  	return ed.L2
 239  }
 240  func (ed *Enum) IsClosed() bool {
 241  	return !ed.L1.EditionFeatures.IsOpenEnum
 242  }
 243  
 244  func (ed *EnumValue) Options() protoreflect.ProtoMessage {
 245  	if f := ed.L1.Options; f != nil {
 246  		return f()
 247  	}
 248  	return descopts.EnumValue
 249  }
 250  func (ed *EnumValue) Number() protoreflect.EnumNumber            { return ed.L1.Number }
 251  func (ed *EnumValue) Format(s fmt.State, r rune)                 { descfmt.FormatDesc(s, r, ed) }
 252  func (ed *EnumValue) ProtoType(protoreflect.EnumValueDescriptor) {}
 253  
 254  type (
 255  	Message struct {
 256  		Base
 257  		L1 MessageL1
 258  		L2 *MessageL2 // protected by fileDesc.once
 259  	}
 260  	MessageL1 struct {
 261  		Enums           Enums
 262  		Messages        Messages
 263  		Extensions      Extensions
 264  		EditionFeatures EditionFeatures
 265  		Visibility      int32
 266  		IsMapEntry      bool // promoted from google.protobuf.MessageOptions
 267  		IsMessageSet    bool // promoted from google.protobuf.MessageOptions
 268  	}
 269  	MessageL2 struct {
 270  		Options               func() protoreflect.ProtoMessage
 271  		Fields                Fields
 272  		Oneofs                Oneofs
 273  		ReservedNames         Names
 274  		ReservedRanges        FieldRanges
 275  		RequiredNumbers       FieldNumbers // must be consistent with Fields.Cardinality
 276  		ExtensionRanges       FieldRanges
 277  		ExtensionRangeOptions []func() protoreflect.ProtoMessage // must be same length as ExtensionRanges
 278  	}
 279  
 280  	Field struct {
 281  		Base
 282  		L1 FieldL1
 283  	}
 284  	FieldL1 struct {
 285  		Options          func() protoreflect.ProtoMessage
 286  		Number           protoreflect.FieldNumber
 287  		Cardinality      protoreflect.Cardinality // must be consistent with Message.RequiredNumbers
 288  		Kind             protoreflect.Kind
 289  		StringName       stringName
 290  		IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto
 291  		IsLazy           bool // promoted from google.protobuf.FieldOptions
 292  		Default          defaultValue
 293  		ContainingOneof  protoreflect.OneofDescriptor // must be consistent with Message.Oneofs.Fields
 294  		Enum             protoreflect.EnumDescriptor
 295  		Message          protoreflect.MessageDescriptor
 296  
 297  		EditionFeatures EditionFeatures
 298  	}
 299  
 300  	Oneof struct {
 301  		Base
 302  		L1 OneofL1
 303  	}
 304  	OneofL1 struct {
 305  		Options func() protoreflect.ProtoMessage
 306  		Fields  OneofFields // must be consistent with Message.Fields.ContainingOneof
 307  
 308  		EditionFeatures EditionFeatures
 309  	}
 310  )
 311  
 312  func (md *Message) Options() protoreflect.ProtoMessage {
 313  	if f := md.lazyInit().Options; f != nil {
 314  		return f()
 315  	}
 316  	return descopts.Message
 317  }
 318  func (md *Message) IsMapEntry() bool                           { return md.L1.IsMapEntry }
 319  func (md *Message) Fields() protoreflect.FieldDescriptors      { return &md.lazyInit().Fields }
 320  func (md *Message) Oneofs() protoreflect.OneofDescriptors      { return &md.lazyInit().Oneofs }
 321  func (md *Message) ReservedNames() protoreflect.Names          { return &md.lazyInit().ReservedNames }
 322  func (md *Message) ReservedRanges() protoreflect.FieldRanges   { return &md.lazyInit().ReservedRanges }
 323  func (md *Message) RequiredNumbers() protoreflect.FieldNumbers { return &md.lazyInit().RequiredNumbers }
 324  func (md *Message) ExtensionRanges() protoreflect.FieldRanges  { return &md.lazyInit().ExtensionRanges }
 325  func (md *Message) ExtensionRangeOptions(i int) protoreflect.ProtoMessage {
 326  	if f := md.lazyInit().ExtensionRangeOptions[i]; f != nil {
 327  		return f()
 328  	}
 329  	return descopts.ExtensionRange
 330  }
 331  func (md *Message) Enums() protoreflect.EnumDescriptors           { return &md.L1.Enums }
 332  func (md *Message) Messages() protoreflect.MessageDescriptors     { return &md.L1.Messages }
 333  func (md *Message) Extensions() protoreflect.ExtensionDescriptors { return &md.L1.Extensions }
 334  func (md *Message) ProtoType(protoreflect.MessageDescriptor)      {}
 335  func (md *Message) Format(s fmt.State, r rune)                    { descfmt.FormatDesc(s, r, md) }
 336  
 337  // This is not part of the MessageDescriptor interface. It is just used to reconstruct
 338  // the original FileDescriptor proto.
 339  func (md *Message) Visibility() int32 { return md.L1.Visibility }
 340  
 341  func (md *Message) lazyInit() *MessageL2 {
 342  	md.L0.ParentFile.lazyInit() // implicitly initializes L2
 343  	return md.L2
 344  }
 345  
 346  // IsMessageSet is a pseudo-internal API for checking whether a message
 347  // should serialize in the proto1 message format.
 348  //
 349  // WARNING: This method is exempt from the compatibility promise and may be
 350  // removed in the future without warning.
 351  func (md *Message) IsMessageSet() bool {
 352  	return md.L1.IsMessageSet
 353  }
 354  
 355  func (fd *Field) Options() protoreflect.ProtoMessage {
 356  	if f := fd.L1.Options; f != nil {
 357  		return f()
 358  	}
 359  	return descopts.Field
 360  }
 361  func (fd *Field) Number() protoreflect.FieldNumber      { return fd.L1.Number }
 362  func (fd *Field) Cardinality() protoreflect.Cardinality { return fd.L1.Cardinality }
 363  func (fd *Field) Kind() protoreflect.Kind {
 364  	return fd.L1.Kind
 365  }
 366  func (fd *Field) HasJSONName() bool { return fd.L1.StringName.hasJSON }
 367  func (fd *Field) JSONName() string  { return fd.L1.StringName.getJSON(fd) }
 368  func (fd *Field) TextName() string  { return fd.L1.StringName.getText(fd) }
 369  func (fd *Field) HasPresence() bool {
 370  	if fd.L1.Cardinality == protoreflect.Repeated {
 371  		return false
 372  	}
 373  	return fd.IsExtension() || fd.L1.EditionFeatures.IsFieldPresence || fd.L1.Message != nil || fd.L1.ContainingOneof != nil
 374  }
 375  func (fd *Field) HasOptionalKeyword() bool {
 376  	return (fd.L0.ParentFile.L1.Syntax == protoreflect.Proto2 && fd.L1.Cardinality == protoreflect.Optional && fd.L1.ContainingOneof == nil) || fd.L1.IsProto3Optional
 377  }
 378  func (fd *Field) IsPacked() bool {
 379  	if fd.L1.Cardinality != protoreflect.Repeated {
 380  		return false
 381  	}
 382  	switch fd.L1.Kind {
 383  	case protoreflect.StringKind, protoreflect.BytesKind, protoreflect.MessageKind, protoreflect.GroupKind:
 384  		return false
 385  	}
 386  	return fd.L1.EditionFeatures.IsPacked
 387  }
 388  func (fd *Field) IsExtension() bool { return false }
 389  func (fd *Field) IsWeak() bool      { return false }
 390  func (fd *Field) IsLazy() bool      { return fd.L1.IsLazy }
 391  func (fd *Field) IsList() bool      { return fd.Cardinality() == protoreflect.Repeated && !fd.IsMap() }
 392  func (fd *Field) IsMap() bool       { return fd.Message() != nil && fd.Message().IsMapEntry() }
 393  func (fd *Field) MapKey() protoreflect.FieldDescriptor {
 394  	if !fd.IsMap() {
 395  		return nil
 396  	}
 397  	return fd.Message().Fields().ByNumber(genid.MapEntry_Key_field_number)
 398  }
 399  func (fd *Field) MapValue() protoreflect.FieldDescriptor {
 400  	if !fd.IsMap() {
 401  		return nil
 402  	}
 403  	return fd.Message().Fields().ByNumber(genid.MapEntry_Value_field_number)
 404  }
 405  func (fd *Field) HasDefault() bool                                   { return fd.L1.Default.has }
 406  func (fd *Field) Default() protoreflect.Value                        { return fd.L1.Default.get(fd) }
 407  func (fd *Field) DefaultEnumValue() protoreflect.EnumValueDescriptor { return fd.L1.Default.enum }
 408  func (fd *Field) ContainingOneof() protoreflect.OneofDescriptor      { return fd.L1.ContainingOneof }
 409  func (fd *Field) ContainingMessage() protoreflect.MessageDescriptor {
 410  	return fd.L0.Parent.(protoreflect.MessageDescriptor)
 411  }
 412  func (fd *Field) Enum() protoreflect.EnumDescriptor {
 413  	return fd.L1.Enum
 414  }
 415  func (fd *Field) Message() protoreflect.MessageDescriptor {
 416  	return fd.L1.Message
 417  }
 418  func (fd *Field) IsMapEntry() bool {
 419  	parent, ok := fd.L0.Parent.(protoreflect.MessageDescriptor)
 420  	return ok && parent.IsMapEntry()
 421  }
 422  func (fd *Field) Format(s fmt.State, r rune)             { descfmt.FormatDesc(s, r, fd) }
 423  func (fd *Field) ProtoType(protoreflect.FieldDescriptor) {}
 424  
 425  // EnforceUTF8 is a pseudo-internal API to determine whether to enforce UTF-8
 426  // validation for the string field. This exists for Google-internal use only
 427  // since proto3 did not enforce UTF-8 validity prior to the open-source release.
 428  // If this method does not exist, the default is to enforce valid UTF-8.
 429  //
 430  // WARNING: This method is exempt from the compatibility promise and may be
 431  // removed in the future without warning.
 432  func (fd *Field) EnforceUTF8() bool {
 433  	return fd.L1.EditionFeatures.IsUTF8Validated
 434  }
 435  
 436  func (od *Oneof) IsSynthetic() bool {
 437  	return od.L0.ParentFile.L1.Syntax == protoreflect.Proto3 && len(od.L1.Fields.List) == 1 && od.L1.Fields.List[0].HasOptionalKeyword()
 438  }
 439  func (od *Oneof) Options() protoreflect.ProtoMessage {
 440  	if f := od.L1.Options; f != nil {
 441  		return f()
 442  	}
 443  	return descopts.Oneof
 444  }
 445  func (od *Oneof) Fields() protoreflect.FieldDescriptors  { return &od.L1.Fields }
 446  func (od *Oneof) Format(s fmt.State, r rune)             { descfmt.FormatDesc(s, r, od) }
 447  func (od *Oneof) ProtoType(protoreflect.OneofDescriptor) {}
 448  
 449  type (
 450  	Extension struct {
 451  		Base
 452  		L1 ExtensionL1
 453  		L2 *ExtensionL2 // protected by fileDesc.once
 454  	}
 455  	ExtensionL1 struct {
 456  		Number          protoreflect.FieldNumber
 457  		Extendee        protoreflect.MessageDescriptor
 458  		Cardinality     protoreflect.Cardinality
 459  		Kind            protoreflect.Kind
 460  		IsLazy          bool
 461  		EditionFeatures EditionFeatures
 462  	}
 463  	ExtensionL2 struct {
 464  		Options          func() protoreflect.ProtoMessage
 465  		StringName       stringName
 466  		IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto
 467  		Default          defaultValue
 468  		Enum             protoreflect.EnumDescriptor
 469  		Message          protoreflect.MessageDescriptor
 470  	}
 471  )
 472  
 473  func (xd *Extension) Options() protoreflect.ProtoMessage {
 474  	if f := xd.lazyInit().Options; f != nil {
 475  		return f()
 476  	}
 477  	return descopts.Field
 478  }
 479  func (xd *Extension) Number() protoreflect.FieldNumber      { return xd.L1.Number }
 480  func (xd *Extension) Cardinality() protoreflect.Cardinality { return xd.L1.Cardinality }
 481  func (xd *Extension) Kind() protoreflect.Kind               { return xd.L1.Kind }
 482  func (xd *Extension) HasJSONName() bool                     { return xd.lazyInit().StringName.hasJSON }
 483  func (xd *Extension) JSONName() string                      { return xd.lazyInit().StringName.getJSON(xd) }
 484  func (xd *Extension) TextName() string                      { return xd.lazyInit().StringName.getText(xd) }
 485  func (xd *Extension) HasPresence() bool                     { return xd.L1.Cardinality != protoreflect.Repeated }
 486  func (xd *Extension) HasOptionalKeyword() bool {
 487  	return (xd.L0.ParentFile.L1.Syntax == protoreflect.Proto2 && xd.L1.Cardinality == protoreflect.Optional) || xd.lazyInit().IsProto3Optional
 488  }
 489  func (xd *Extension) IsPacked() bool {
 490  	if xd.L1.Cardinality != protoreflect.Repeated {
 491  		return false
 492  	}
 493  	switch xd.L1.Kind {
 494  	case protoreflect.StringKind, protoreflect.BytesKind, protoreflect.MessageKind, protoreflect.GroupKind:
 495  		return false
 496  	}
 497  	return xd.L1.EditionFeatures.IsPacked
 498  }
 499  func (xd *Extension) IsExtension() bool                      { return true }
 500  func (xd *Extension) IsWeak() bool                           { return false }
 501  func (xd *Extension) IsLazy() bool                           { return xd.L1.IsLazy }
 502  func (xd *Extension) IsList() bool                           { return xd.Cardinality() == protoreflect.Repeated }
 503  func (xd *Extension) IsMap() bool                            { return false }
 504  func (xd *Extension) MapKey() protoreflect.FieldDescriptor   { return nil }
 505  func (xd *Extension) MapValue() protoreflect.FieldDescriptor { return nil }
 506  func (xd *Extension) HasDefault() bool                       { return xd.lazyInit().Default.has }
 507  func (xd *Extension) Default() protoreflect.Value            { return xd.lazyInit().Default.get(xd) }
 508  func (xd *Extension) DefaultEnumValue() protoreflect.EnumValueDescriptor {
 509  	return xd.lazyInit().Default.enum
 510  }
 511  func (xd *Extension) ContainingOneof() protoreflect.OneofDescriptor     { return nil }
 512  func (xd *Extension) ContainingMessage() protoreflect.MessageDescriptor { return xd.L1.Extendee }
 513  func (xd *Extension) Enum() protoreflect.EnumDescriptor                 { return xd.lazyInit().Enum }
 514  func (xd *Extension) Message() protoreflect.MessageDescriptor           { return xd.lazyInit().Message }
 515  func (xd *Extension) Format(s fmt.State, r rune)                        { descfmt.FormatDesc(s, r, xd) }
 516  func (xd *Extension) ProtoType(protoreflect.FieldDescriptor)            {}
 517  func (xd *Extension) ProtoInternal(pragma.DoNotImplement)               {}
 518  func (xd *Extension) lazyInit() *ExtensionL2 {
 519  	xd.L0.ParentFile.lazyInit() // implicitly initializes L2
 520  	return xd.L2
 521  }
 522  
 523  type (
 524  	Service struct {
 525  		Base
 526  		L1 ServiceL1
 527  		L2 *ServiceL2 // protected by fileDesc.once
 528  	}
 529  	ServiceL1 struct{}
 530  	ServiceL2 struct {
 531  		Options func() protoreflect.ProtoMessage
 532  		Methods Methods
 533  	}
 534  
 535  	Method struct {
 536  		Base
 537  		L1 MethodL1
 538  	}
 539  	MethodL1 struct {
 540  		Options           func() protoreflect.ProtoMessage
 541  		Input             protoreflect.MessageDescriptor
 542  		Output            protoreflect.MessageDescriptor
 543  		IsStreamingClient bool
 544  		IsStreamingServer bool
 545  	}
 546  )
 547  
 548  func (sd *Service) Options() protoreflect.ProtoMessage {
 549  	if f := sd.lazyInit().Options; f != nil {
 550  		return f()
 551  	}
 552  	return descopts.Service
 553  }
 554  func (sd *Service) Methods() protoreflect.MethodDescriptors  { return &sd.lazyInit().Methods }
 555  func (sd *Service) Format(s fmt.State, r rune)               { descfmt.FormatDesc(s, r, sd) }
 556  func (sd *Service) ProtoType(protoreflect.ServiceDescriptor) {}
 557  func (sd *Service) ProtoInternal(pragma.DoNotImplement)      {}
 558  func (sd *Service) lazyInit() *ServiceL2 {
 559  	sd.L0.ParentFile.lazyInit() // implicitly initializes L2
 560  	return sd.L2
 561  }
 562  
 563  func (md *Method) Options() protoreflect.ProtoMessage {
 564  	if f := md.L1.Options; f != nil {
 565  		return f()
 566  	}
 567  	return descopts.Method
 568  }
 569  func (md *Method) Input() protoreflect.MessageDescriptor   { return md.L1.Input }
 570  func (md *Method) Output() protoreflect.MessageDescriptor  { return md.L1.Output }
 571  func (md *Method) IsStreamingClient() bool                 { return md.L1.IsStreamingClient }
 572  func (md *Method) IsStreamingServer() bool                 { return md.L1.IsStreamingServer }
 573  func (md *Method) Format(s fmt.State, r rune)              { descfmt.FormatDesc(s, r, md) }
 574  func (md *Method) ProtoType(protoreflect.MethodDescriptor) {}
 575  func (md *Method) ProtoInternal(pragma.DoNotImplement)     {}
 576  
 577  // Surrogate files are can be used to create standalone descriptors
 578  // where the syntax is only information derived from the parent file.
 579  var (
 580  	SurrogateProto2      = &File{L1: FileL1{Syntax: protoreflect.Proto2}, L2: &FileL2{}}
 581  	SurrogateProto3      = &File{L1: FileL1{Syntax: protoreflect.Proto3}, L2: &FileL2{}}
 582  	SurrogateEdition2023 = &File{L1: FileL1{Syntax: protoreflect.Editions, Edition: Edition2023}, L2: &FileL2{}}
 583  )
 584  
 585  type (
 586  	Base struct {
 587  		L0 BaseL0
 588  	}
 589  	BaseL0 struct {
 590  		FullName   protoreflect.FullName // must be populated
 591  		ParentFile *File                 // must be populated
 592  		Parent     protoreflect.Descriptor
 593  		Index      int
 594  	}
 595  )
 596  
 597  func (d *Base) Name() protoreflect.Name         { return d.L0.FullName.Name() }
 598  func (d *Base) FullName() protoreflect.FullName { return d.L0.FullName }
 599  func (d *Base) ParentFile() protoreflect.FileDescriptor {
 600  	if d.L0.ParentFile == SurrogateProto2 || d.L0.ParentFile == SurrogateProto3 {
 601  		return nil // surrogate files are not real parents
 602  	}
 603  	return d.L0.ParentFile
 604  }
 605  func (d *Base) Parent() protoreflect.Descriptor     { return d.L0.Parent }
 606  func (d *Base) Index() int                          { return d.L0.Index }
 607  func (d *Base) Syntax() protoreflect.Syntax         { return d.L0.ParentFile.Syntax() }
 608  func (d *Base) IsPlaceholder() bool                 { return false }
 609  func (d *Base) ProtoInternal(pragma.DoNotImplement) {}
 610  
 611  type stringName struct {
 612  	hasJSON  bool
 613  	once     sync.Once
 614  	nameJSON string
 615  	nameText string
 616  }
 617  
 618  // InitJSON initializes the name. It is exported for use by other internal packages.
 619  func (s *stringName) InitJSON(name string) {
 620  	s.hasJSON = true
 621  	s.nameJSON = name
 622  }
 623  
 624  // Returns true if this field is structured like the synthetic field of a proto2
 625  // group. This allows us to expand our treatment of delimited fields without
 626  // breaking proto2 files that have been upgraded to editions.
 627  func isGroupLike(fd protoreflect.FieldDescriptor) bool {
 628  	// Groups are always group types.
 629  	if fd.Kind() != protoreflect.GroupKind {
 630  		return false
 631  	}
 632  
 633  	// Group fields are always the lowercase type name.
 634  	if strings.ToLower(string(fd.Message().Name())) != string(fd.Name()) {
 635  		return false
 636  	}
 637  
 638  	// Groups could only be defined in the same file they're used.
 639  	if fd.Message().ParentFile() != fd.ParentFile() {
 640  		return false
 641  	}
 642  
 643  	// Group messages are always defined in the same scope as the field.  File
 644  	// level extensions will compare NULL == NULL here, which is why the file
 645  	// comparison above is necessary to ensure both come from the same file.
 646  	if fd.IsExtension() {
 647  		return fd.Parent() == fd.Message().Parent()
 648  	}
 649  	return fd.ContainingMessage() == fd.Message().Parent()
 650  }
 651  
 652  func (s *stringName) lazyInit(fd protoreflect.FieldDescriptor) *stringName {
 653  	s.once.Do(func() {
 654  		if fd.IsExtension() {
 655  			// For extensions, JSON and text are formatted the same way.
 656  			var name string
 657  			if messageset.IsMessageSetExtension(fd) {
 658  				name = string("[" + fd.FullName().Parent() + "]")
 659  			} else {
 660  				name = string("[" + fd.FullName() + "]")
 661  			}
 662  			s.nameJSON = name
 663  			s.nameText = name
 664  		} else {
 665  			// Format the JSON name.
 666  			if !s.hasJSON {
 667  				s.nameJSON = strs.JSONCamelCase(string(fd.Name()))
 668  			}
 669  
 670  			// Format the text name.
 671  			s.nameText = string(fd.Name())
 672  			if isGroupLike(fd) {
 673  				s.nameText = string(fd.Message().Name())
 674  			}
 675  		}
 676  	})
 677  	return s
 678  }
 679  
 680  func (s *stringName) getJSON(fd protoreflect.FieldDescriptor) string { return s.lazyInit(fd).nameJSON }
 681  func (s *stringName) getText(fd protoreflect.FieldDescriptor) string { return s.lazyInit(fd).nameText }
 682  
 683  func DefaultValue(v protoreflect.Value, ev protoreflect.EnumValueDescriptor) defaultValue {
 684  	dv := defaultValue{has: v.IsValid(), val: v, enum: ev}
 685  	if b, ok := v.Interface().([]byte); ok {
 686  		// Store a copy of the default bytes, so that we can detect
 687  		// accidental mutations of the original value.
 688  		dv.bytes = append([]byte(nil), b...)
 689  	}
 690  	return dv
 691  }
 692  
 693  func unmarshalDefault(b []byte, k protoreflect.Kind, pf *File, ed protoreflect.EnumDescriptor) defaultValue {
 694  	var evs protoreflect.EnumValueDescriptors
 695  	if k == protoreflect.EnumKind {
 696  		// If the enum is declared within the same file, be careful not to
 697  		// blindly call the Values method, lest we bind ourselves in a deadlock.
 698  		if e, ok := ed.(*Enum); ok && e.L0.ParentFile == pf {
 699  			evs = &e.L2.Values
 700  		} else {
 701  			evs = ed.Values()
 702  		}
 703  
 704  		// If we are unable to resolve the enum dependency, use a placeholder
 705  		// enum value since we will not be able to parse the default value.
 706  		if ed.IsPlaceholder() && protoreflect.Name(b).IsValid() {
 707  			v := protoreflect.ValueOfEnum(0)
 708  			ev := PlaceholderEnumValue(ed.FullName().Parent().Append(protoreflect.Name(b)))
 709  			return DefaultValue(v, ev)
 710  		}
 711  	}
 712  
 713  	v, ev, err := defval.Unmarshal(string(b), k, evs, defval.Descriptor)
 714  	if err != nil {
 715  		panic(err)
 716  	}
 717  	return DefaultValue(v, ev)
 718  }
 719  
 720  type defaultValue struct {
 721  	has   bool
 722  	val   protoreflect.Value
 723  	enum  protoreflect.EnumValueDescriptor
 724  	bytes []byte
 725  }
 726  
 727  func (dv *defaultValue) get(fd protoreflect.FieldDescriptor) protoreflect.Value {
 728  	// Return the zero value as the default if unpopulated.
 729  	if !dv.has {
 730  		if fd.Cardinality() == protoreflect.Repeated {
 731  			return protoreflect.Value{}
 732  		}
 733  		switch fd.Kind() {
 734  		case protoreflect.BoolKind:
 735  			return protoreflect.ValueOfBool(false)
 736  		case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
 737  			return protoreflect.ValueOfInt32(0)
 738  		case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
 739  			return protoreflect.ValueOfInt64(0)
 740  		case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
 741  			return protoreflect.ValueOfUint32(0)
 742  		case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
 743  			return protoreflect.ValueOfUint64(0)
 744  		case protoreflect.FloatKind:
 745  			return protoreflect.ValueOfFloat32(0)
 746  		case protoreflect.DoubleKind:
 747  			return protoreflect.ValueOfFloat64(0)
 748  		case protoreflect.StringKind:
 749  			return protoreflect.ValueOfString("")
 750  		case protoreflect.BytesKind:
 751  			return protoreflect.ValueOfBytes(nil)
 752  		case protoreflect.EnumKind:
 753  			if evs := fd.Enum().Values(); evs.Len() > 0 {
 754  				return protoreflect.ValueOfEnum(evs.Get(0).Number())
 755  			}
 756  			return protoreflect.ValueOfEnum(0)
 757  		}
 758  	}
 759  
 760  	if len(dv.bytes) > 0 && !bytes.Equal(dv.bytes, dv.val.Bytes()) {
 761  		// TODO: Avoid panic if we're running with the race detector
 762  		// and instead spawn a goroutine that periodically resets
 763  		// this value back to the original to induce a race.
 764  		panic(fmt.Sprintf("detected mutation on the default bytes for %v", fd.FullName()))
 765  	}
 766  	return dv.val
 767  }
 768