github.com/jhump/protoreflect@v1.16.0/desc/internal/util.go (about)

     1  package internal
     2  
     3  import (
     4  	"math"
     5  	"unicode"
     6  	"unicode/utf8"
     7  )
     8  
     9  const (
    10  	// MaxNormalTag is the maximum allowed tag number for a field in a normal message.
    11  	MaxNormalTag = 536870911 // 2^29 - 1
    12  
    13  	// MaxMessageSetTag is the maximum allowed tag number of a field in a message that
    14  	// uses the message set wire format.
    15  	MaxMessageSetTag = math.MaxInt32 - 1
    16  
    17  	// MaxTag is the maximum allowed tag number. (It is the same as MaxMessageSetTag
    18  	// since that is the absolute highest allowed.)
    19  	MaxTag = MaxMessageSetTag
    20  
    21  	// SpecialReservedStart is the first tag in a range that is reserved and not
    22  	// allowed for use in message definitions.
    23  	SpecialReservedStart = 19000
    24  	// SpecialReservedEnd is the last tag in a range that is reserved and not
    25  	// allowed for use in message definitions.
    26  	SpecialReservedEnd = 19999
    27  
    28  	// NB: It would be nice to use constants from generated code instead of
    29  	// hard-coding these here. But code-gen does not emit these as constants
    30  	// anywhere. The only places they appear in generated code are struct tags
    31  	// on fields of the generated descriptor protos.
    32  
    33  	// File_packageTag is the tag number of the package element in a file
    34  	// descriptor proto.
    35  	File_packageTag = 2
    36  	// File_dependencyTag is the tag number of the dependencies element in a
    37  	// file descriptor proto.
    38  	File_dependencyTag = 3
    39  	// File_messagesTag is the tag number of the messages element in a file
    40  	// descriptor proto.
    41  	File_messagesTag = 4
    42  	// File_enumsTag is the tag number of the enums element in a file descriptor
    43  	// proto.
    44  	File_enumsTag = 5
    45  	// File_servicesTag is the tag number of the services element in a file
    46  	// descriptor proto.
    47  	File_servicesTag = 6
    48  	// File_extensionsTag is the tag number of the extensions element in a file
    49  	// descriptor proto.
    50  	File_extensionsTag = 7
    51  	// File_optionsTag is the tag number of the options element in a file
    52  	// descriptor proto.
    53  	File_optionsTag = 8
    54  	// File_syntaxTag is the tag number of the syntax element in a file
    55  	// descriptor proto.
    56  	File_syntaxTag = 12
    57  	// File_editionTag is the tag number of the edition element in a file
    58  	// descriptor proto.
    59  	File_editionTag = 14
    60  	// Message_nameTag is the tag number of the name element in a message
    61  	// descriptor proto.
    62  	Message_nameTag = 1
    63  	// Message_fieldsTag is the tag number of the fields element in a message
    64  	// descriptor proto.
    65  	Message_fieldsTag = 2
    66  	// Message_nestedMessagesTag is the tag number of the nested messages
    67  	// element in a message descriptor proto.
    68  	Message_nestedMessagesTag = 3
    69  	// Message_enumsTag is the tag number of the enums element in a message
    70  	// descriptor proto.
    71  	Message_enumsTag = 4
    72  	// Message_extensionRangeTag is the tag number of the extension ranges
    73  	// element in a message descriptor proto.
    74  	Message_extensionRangeTag = 5
    75  	// Message_extensionsTag is the tag number of the extensions element in a
    76  	// message descriptor proto.
    77  	Message_extensionsTag = 6
    78  	// Message_optionsTag is the tag number of the options element in a message
    79  	// descriptor proto.
    80  	Message_optionsTag = 7
    81  	// Message_oneOfsTag is the tag number of the one-ofs element in a message
    82  	// descriptor proto.
    83  	Message_oneOfsTag = 8
    84  	// Message_reservedRangeTag is the tag number of the reserved ranges element
    85  	// in a message descriptor proto.
    86  	Message_reservedRangeTag = 9
    87  	// Message_reservedNameTag is the tag number of the reserved names element
    88  	// in a message descriptor proto.
    89  	Message_reservedNameTag = 10
    90  	// ExtensionRange_startTag is the tag number of the start index in an
    91  	// extension range proto.
    92  	ExtensionRange_startTag = 1
    93  	// ExtensionRange_endTag is the tag number of the end index in an
    94  	// extension range proto.
    95  	ExtensionRange_endTag = 2
    96  	// ExtensionRange_optionsTag is the tag number of the options element in an
    97  	// extension range proto.
    98  	ExtensionRange_optionsTag = 3
    99  	// ReservedRange_startTag is the tag number of the start index in a reserved
   100  	// range proto.
   101  	ReservedRange_startTag = 1
   102  	// ReservedRange_endTag is the tag number of the end index in a reserved
   103  	// range proto.
   104  	ReservedRange_endTag = 2
   105  	// Field_nameTag is the tag number of the name element in a field descriptor
   106  	// proto.
   107  	Field_nameTag = 1
   108  	// Field_extendeeTag is the tag number of the extendee element in a field
   109  	// descriptor proto.
   110  	Field_extendeeTag = 2
   111  	// Field_numberTag is the tag number of the number element in a field
   112  	// descriptor proto.
   113  	Field_numberTag = 3
   114  	// Field_labelTag is the tag number of the label element in a field
   115  	// descriptor proto.
   116  	Field_labelTag = 4
   117  	// Field_typeTag is the tag number of the type element in a field descriptor
   118  	// proto.
   119  	Field_typeTag = 5
   120  	// Field_typeNameTag is the tag number of the type name element in a field
   121  	// descriptor proto.
   122  	Field_typeNameTag = 6
   123  	// Field_defaultTag is the tag number of the default value element in a
   124  	// field descriptor proto.
   125  	Field_defaultTag = 7
   126  	// Field_optionsTag is the tag number of the options element in a field
   127  	// descriptor proto.
   128  	Field_optionsTag = 8
   129  	// Field_jsonNameTag is the tag number of the JSON name element in a field
   130  	// descriptor proto.
   131  	Field_jsonNameTag = 10
   132  	// Field_proto3OptionalTag is the tag number of the proto3_optional element
   133  	// in a descriptor proto.
   134  	Field_proto3OptionalTag = 17
   135  	// OneOf_nameTag is the tag number of the name element in a one-of
   136  	// descriptor proto.
   137  	OneOf_nameTag = 1
   138  	// OneOf_optionsTag is the tag number of the options element in a one-of
   139  	// descriptor proto.
   140  	OneOf_optionsTag = 2
   141  	// Enum_nameTag is the tag number of the name element in an enum descriptor
   142  	// proto.
   143  	Enum_nameTag = 1
   144  	// Enum_valuesTag is the tag number of the values element in an enum
   145  	// descriptor proto.
   146  	Enum_valuesTag = 2
   147  	// Enum_optionsTag is the tag number of the options element in an enum
   148  	// descriptor proto.
   149  	Enum_optionsTag = 3
   150  	// Enum_reservedRangeTag is the tag number of the reserved ranges element in
   151  	// an enum descriptor proto.
   152  	Enum_reservedRangeTag = 4
   153  	// Enum_reservedNameTag is the tag number of the reserved names element in
   154  	// an enum descriptor proto.
   155  	Enum_reservedNameTag = 5
   156  	// EnumVal_nameTag is the tag number of the name element in an enum value
   157  	// descriptor proto.
   158  	EnumVal_nameTag = 1
   159  	// EnumVal_numberTag is the tag number of the number element in an enum
   160  	// value descriptor proto.
   161  	EnumVal_numberTag = 2
   162  	// EnumVal_optionsTag is the tag number of the options element in an enum
   163  	// value descriptor proto.
   164  	EnumVal_optionsTag = 3
   165  	// Service_nameTag is the tag number of the name element in a service
   166  	// descriptor proto.
   167  	Service_nameTag = 1
   168  	// Service_methodsTag is the tag number of the methods element in a service
   169  	// descriptor proto.
   170  	Service_methodsTag = 2
   171  	// Service_optionsTag is the tag number of the options element in a service
   172  	// descriptor proto.
   173  	Service_optionsTag = 3
   174  	// Method_nameTag is the tag number of the name element in a method
   175  	// descriptor proto.
   176  	Method_nameTag = 1
   177  	// Method_inputTag is the tag number of the input type element in a method
   178  	// descriptor proto.
   179  	Method_inputTag = 2
   180  	// Method_outputTag is the tag number of the output type element in a method
   181  	// descriptor proto.
   182  	Method_outputTag = 3
   183  	// Method_optionsTag is the tag number of the options element in a method
   184  	// descriptor proto.
   185  	Method_optionsTag = 4
   186  	// Method_inputStreamTag is the tag number of the input stream flag in a
   187  	// method descriptor proto.
   188  	Method_inputStreamTag = 5
   189  	// Method_outputStreamTag is the tag number of the output stream flag in a
   190  	// method descriptor proto.
   191  	Method_outputStreamTag = 6
   192  
   193  	// UninterpretedOptionsTag is the tag number of the uninterpreted options
   194  	// element. All *Options messages use the same tag for the field that stores
   195  	// uninterpreted options.
   196  	UninterpretedOptionsTag = 999
   197  
   198  	// Uninterpreted_nameTag is the tag number of the name element in an
   199  	// uninterpreted options proto.
   200  	Uninterpreted_nameTag = 2
   201  	// Uninterpreted_identTag is the tag number of the identifier value in an
   202  	// uninterpreted options proto.
   203  	Uninterpreted_identTag = 3
   204  	// Uninterpreted_posIntTag is the tag number of the positive int value in an
   205  	// uninterpreted options proto.
   206  	Uninterpreted_posIntTag = 4
   207  	// Uninterpreted_negIntTag is the tag number of the negative int value in an
   208  	// uninterpreted options proto.
   209  	Uninterpreted_negIntTag = 5
   210  	// Uninterpreted_doubleTag is the tag number of the double value in an
   211  	// uninterpreted options proto.
   212  	Uninterpreted_doubleTag = 6
   213  	// Uninterpreted_stringTag is the tag number of the string value in an
   214  	// uninterpreted options proto.
   215  	Uninterpreted_stringTag = 7
   216  	// Uninterpreted_aggregateTag is the tag number of the aggregate value in an
   217  	// uninterpreted options proto.
   218  	Uninterpreted_aggregateTag = 8
   219  	// UninterpretedName_nameTag is the tag number of the name element in an
   220  	// uninterpreted option name proto.
   221  	UninterpretedName_nameTag = 1
   222  )
   223  
   224  // JsonName returns the default JSON name for a field with the given name.
   225  // This mirrors the algorithm in protoc:
   226  //
   227  //	https://github.com/protocolbuffers/protobuf/blob/v21.3/src/google/protobuf/descriptor.cc#L95
   228  func JsonName(name string) string {
   229  	var js []rune
   230  	nextUpper := false
   231  	for _, r := range name {
   232  		if r == '_' {
   233  			nextUpper = true
   234  			continue
   235  		}
   236  		if nextUpper {
   237  			nextUpper = false
   238  			js = append(js, unicode.ToUpper(r))
   239  		} else {
   240  			js = append(js, r)
   241  		}
   242  	}
   243  	return string(js)
   244  }
   245  
   246  // InitCap returns the given field name, but with the first letter capitalized.
   247  func InitCap(name string) string {
   248  	r, sz := utf8.DecodeRuneInString(name)
   249  	return string(unicode.ToUpper(r)) + name[sz:]
   250  }
   251  
   252  // CreatePrefixList returns a list of package prefixes to search when resolving
   253  // a symbol name. If the given package is blank, it returns only the empty
   254  // string. If the given package contains only one token, e.g. "foo", it returns
   255  // that token and the empty string, e.g. ["foo", ""]. Otherwise, it returns
   256  // successively shorter prefixes of the package and then the empty string. For
   257  // example, for a package named "foo.bar.baz" it will return the following list:
   258  //
   259  //	["foo.bar.baz", "foo.bar", "foo", ""]
   260  func CreatePrefixList(pkg string) []string {
   261  	if pkg == "" {
   262  		return []string{""}
   263  	}
   264  
   265  	numDots := 0
   266  	// one pass to pre-allocate the returned slice
   267  	for i := 0; i < len(pkg); i++ {
   268  		if pkg[i] == '.' {
   269  			numDots++
   270  		}
   271  	}
   272  	if numDots == 0 {
   273  		return []string{pkg, ""}
   274  	}
   275  
   276  	prefixes := make([]string, numDots+2)
   277  	// second pass to fill in returned slice
   278  	for i := 0; i < len(pkg); i++ {
   279  		if pkg[i] == '.' {
   280  			prefixes[numDots] = pkg[:i]
   281  			numDots--
   282  		}
   283  	}
   284  	prefixes[0] = pkg
   285  
   286  	return prefixes
   287  }
   288  
   289  // GetMaxTag returns the max tag number allowed, based on whether a message uses
   290  // message set wire format or not.
   291  func GetMaxTag(isMessageSet bool) int32 {
   292  	if isMessageSet {
   293  		return MaxMessageSetTag
   294  	}
   295  	return MaxNormalTag
   296  }