Elia Battiston | ac8d23f | 2022-03-14 17:54:56 +0100 | [diff] [blame^] | 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 | // Message_nameTag is the tag number of the name element in a message |
| 58 | // descriptor proto. |
| 59 | Message_nameTag = 1 |
| 60 | // Message_fieldsTag is the tag number of the fields element in a message |
| 61 | // descriptor proto. |
| 62 | Message_fieldsTag = 2 |
| 63 | // Message_nestedMessagesTag is the tag number of the nested messages |
| 64 | // element in a message descriptor proto. |
| 65 | Message_nestedMessagesTag = 3 |
| 66 | // Message_enumsTag is the tag number of the enums element in a message |
| 67 | // descriptor proto. |
| 68 | Message_enumsTag = 4 |
| 69 | // Message_extensionRangeTag is the tag number of the extension ranges |
| 70 | // element in a message descriptor proto. |
| 71 | Message_extensionRangeTag = 5 |
| 72 | // Message_extensionsTag is the tag number of the extensions element in a |
| 73 | // message descriptor proto. |
| 74 | Message_extensionsTag = 6 |
| 75 | // Message_optionsTag is the tag number of the options element in a message |
| 76 | // descriptor proto. |
| 77 | Message_optionsTag = 7 |
| 78 | // Message_oneOfsTag is the tag number of the one-ofs element in a message |
| 79 | // descriptor proto. |
| 80 | Message_oneOfsTag = 8 |
| 81 | // Message_reservedRangeTag is the tag number of the reserved ranges element |
| 82 | // in a message descriptor proto. |
| 83 | Message_reservedRangeTag = 9 |
| 84 | // Message_reservedNameTag is the tag number of the reserved names element |
| 85 | // in a message descriptor proto. |
| 86 | Message_reservedNameTag = 10 |
| 87 | // ExtensionRange_startTag is the tag number of the start index in an |
| 88 | // extension range proto. |
| 89 | ExtensionRange_startTag = 1 |
| 90 | // ExtensionRange_endTag is the tag number of the end index in an |
| 91 | // extension range proto. |
| 92 | ExtensionRange_endTag = 2 |
| 93 | // ExtensionRange_optionsTag is the tag number of the options element in an |
| 94 | // extension range proto. |
| 95 | ExtensionRange_optionsTag = 3 |
| 96 | // ReservedRange_startTag is the tag number of the start index in a reserved |
| 97 | // range proto. |
| 98 | ReservedRange_startTag = 1 |
| 99 | // ReservedRange_endTag is the tag number of the end index in a reserved |
| 100 | // range proto. |
| 101 | ReservedRange_endTag = 2 |
| 102 | // Field_nameTag is the tag number of the name element in a field descriptor |
| 103 | // proto. |
| 104 | Field_nameTag = 1 |
| 105 | // Field_extendeeTag is the tag number of the extendee element in a field |
| 106 | // descriptor proto. |
| 107 | Field_extendeeTag = 2 |
| 108 | // Field_numberTag is the tag number of the number element in a field |
| 109 | // descriptor proto. |
| 110 | Field_numberTag = 3 |
| 111 | // Field_labelTag is the tag number of the label element in a field |
| 112 | // descriptor proto. |
| 113 | Field_labelTag = 4 |
| 114 | // Field_typeTag is the tag number of the type element in a field descriptor |
| 115 | // proto. |
| 116 | Field_typeTag = 5 |
| 117 | // Field_typeNameTag is the tag number of the type name element in a field |
| 118 | // descriptor proto. |
| 119 | Field_typeNameTag = 6 |
| 120 | // Field_defaultTag is the tag number of the default value element in a |
| 121 | // field descriptor proto. |
| 122 | Field_defaultTag = 7 |
| 123 | // Field_optionsTag is the tag number of the options element in a field |
| 124 | // descriptor proto. |
| 125 | Field_optionsTag = 8 |
| 126 | // Field_jsonNameTag is the tag number of the JSON name element in a field |
| 127 | // descriptor proto. |
| 128 | Field_jsonNameTag = 10 |
| 129 | // Field_proto3OptionalTag is the tag number of the proto3_optional element |
| 130 | // in a descriptor proto. |
| 131 | Field_proto3OptionalTag = 17 |
| 132 | // OneOf_nameTag is the tag number of the name element in a one-of |
| 133 | // descriptor proto. |
| 134 | OneOf_nameTag = 1 |
| 135 | // OneOf_optionsTag is the tag number of the options element in a one-of |
| 136 | // descriptor proto. |
| 137 | OneOf_optionsTag = 2 |
| 138 | // Enum_nameTag is the tag number of the name element in an enum descriptor |
| 139 | // proto. |
| 140 | Enum_nameTag = 1 |
| 141 | // Enum_valuesTag is the tag number of the values element in an enum |
| 142 | // descriptor proto. |
| 143 | Enum_valuesTag = 2 |
| 144 | // Enum_optionsTag is the tag number of the options element in an enum |
| 145 | // descriptor proto. |
| 146 | Enum_optionsTag = 3 |
| 147 | // Enum_reservedRangeTag is the tag number of the reserved ranges element in |
| 148 | // an enum descriptor proto. |
| 149 | Enum_reservedRangeTag = 4 |
| 150 | // Enum_reservedNameTag is the tag number of the reserved names element in |
| 151 | // an enum descriptor proto. |
| 152 | Enum_reservedNameTag = 5 |
| 153 | // EnumVal_nameTag is the tag number of the name element in an enum value |
| 154 | // descriptor proto. |
| 155 | EnumVal_nameTag = 1 |
| 156 | // EnumVal_numberTag is the tag number of the number element in an enum |
| 157 | // value descriptor proto. |
| 158 | EnumVal_numberTag = 2 |
| 159 | // EnumVal_optionsTag is the tag number of the options element in an enum |
| 160 | // value descriptor proto. |
| 161 | EnumVal_optionsTag = 3 |
| 162 | // Service_nameTag is the tag number of the name element in a service |
| 163 | // descriptor proto. |
| 164 | Service_nameTag = 1 |
| 165 | // Service_methodsTag is the tag number of the methods element in a service |
| 166 | // descriptor proto. |
| 167 | Service_methodsTag = 2 |
| 168 | // Service_optionsTag is the tag number of the options element in a service |
| 169 | // descriptor proto. |
| 170 | Service_optionsTag = 3 |
| 171 | // Method_nameTag is the tag number of the name element in a method |
| 172 | // descriptor proto. |
| 173 | Method_nameTag = 1 |
| 174 | // Method_inputTag is the tag number of the input type element in a method |
| 175 | // descriptor proto. |
| 176 | Method_inputTag = 2 |
| 177 | // Method_outputTag is the tag number of the output type element in a method |
| 178 | // descriptor proto. |
| 179 | Method_outputTag = 3 |
| 180 | // Method_optionsTag is the tag number of the options element in a method |
| 181 | // descriptor proto. |
| 182 | Method_optionsTag = 4 |
| 183 | // Method_inputStreamTag is the tag number of the input stream flag in a |
| 184 | // method descriptor proto. |
| 185 | Method_inputStreamTag = 5 |
| 186 | // Method_outputStreamTag is the tag number of the output stream flag in a |
| 187 | // method descriptor proto. |
| 188 | Method_outputStreamTag = 6 |
| 189 | |
| 190 | // UninterpretedOptionsTag is the tag number of the uninterpreted options |
| 191 | // element. All *Options messages use the same tag for the field that stores |
| 192 | // uninterpreted options. |
| 193 | UninterpretedOptionsTag = 999 |
| 194 | |
| 195 | // Uninterpreted_nameTag is the tag number of the name element in an |
| 196 | // uninterpreted options proto. |
| 197 | Uninterpreted_nameTag = 2 |
| 198 | // Uninterpreted_identTag is the tag number of the identifier value in an |
| 199 | // uninterpreted options proto. |
| 200 | Uninterpreted_identTag = 3 |
| 201 | // Uninterpreted_posIntTag is the tag number of the positive int value in an |
| 202 | // uninterpreted options proto. |
| 203 | Uninterpreted_posIntTag = 4 |
| 204 | // Uninterpreted_negIntTag is the tag number of the negative int value in an |
| 205 | // uninterpreted options proto. |
| 206 | Uninterpreted_negIntTag = 5 |
| 207 | // Uninterpreted_doubleTag is the tag number of the double value in an |
| 208 | // uninterpreted options proto. |
| 209 | Uninterpreted_doubleTag = 6 |
| 210 | // Uninterpreted_stringTag is the tag number of the string value in an |
| 211 | // uninterpreted options proto. |
| 212 | Uninterpreted_stringTag = 7 |
| 213 | // Uninterpreted_aggregateTag is the tag number of the aggregate value in an |
| 214 | // uninterpreted options proto. |
| 215 | Uninterpreted_aggregateTag = 8 |
| 216 | // UninterpretedName_nameTag is the tag number of the name element in an |
| 217 | // uninterpreted option name proto. |
| 218 | UninterpretedName_nameTag = 1 |
| 219 | ) |
| 220 | |
| 221 | // JsonName returns the default JSON name for a field with the given name. |
| 222 | func JsonName(name string) string { |
| 223 | var js []rune |
| 224 | nextUpper := false |
| 225 | for i, r := range name { |
| 226 | if r == '_' { |
| 227 | nextUpper = true |
| 228 | continue |
| 229 | } |
| 230 | if i == 0 { |
| 231 | js = append(js, r) |
| 232 | } else if nextUpper { |
| 233 | nextUpper = false |
| 234 | js = append(js, unicode.ToUpper(r)) |
| 235 | } else { |
| 236 | js = append(js, r) |
| 237 | } |
| 238 | } |
| 239 | return string(js) |
| 240 | } |
| 241 | |
| 242 | // InitCap returns the given field name, but with the first letter capitalized. |
| 243 | func InitCap(name string) string { |
| 244 | r, sz := utf8.DecodeRuneInString(name) |
| 245 | return string(unicode.ToUpper(r)) + name[sz:] |
| 246 | } |
| 247 | |
| 248 | // CreatePrefixList returns a list of package prefixes to search when resolving |
| 249 | // a symbol name. If the given package is blank, it returns only the empty |
| 250 | // string. If the given package contains only one token, e.g. "foo", it returns |
| 251 | // that token and the empty string, e.g. ["foo", ""]. Otherwise, it returns |
| 252 | // successively shorter prefixes of the package and then the empty string. For |
| 253 | // example, for a package named "foo.bar.baz" it will return the following list: |
| 254 | // ["foo.bar.baz", "foo.bar", "foo", ""] |
| 255 | func CreatePrefixList(pkg string) []string { |
| 256 | if pkg == "" { |
| 257 | return []string{""} |
| 258 | } |
| 259 | |
| 260 | numDots := 0 |
| 261 | // one pass to pre-allocate the returned slice |
| 262 | for i := 0; i < len(pkg); i++ { |
| 263 | if pkg[i] == '.' { |
| 264 | numDots++ |
| 265 | } |
| 266 | } |
| 267 | if numDots == 0 { |
| 268 | return []string{pkg, ""} |
| 269 | } |
| 270 | |
| 271 | prefixes := make([]string, numDots+2) |
| 272 | // second pass to fill in returned slice |
| 273 | for i := 0; i < len(pkg); i++ { |
| 274 | if pkg[i] == '.' { |
| 275 | prefixes[numDots] = pkg[:i] |
| 276 | numDots-- |
| 277 | } |
| 278 | } |
| 279 | prefixes[0] = pkg |
| 280 | |
| 281 | return prefixes |
| 282 | } |
| 283 | |
| 284 | // GetMaxTag returns the max tag number allowed, based on whether a message uses |
| 285 | // message set wire format or not. |
| 286 | func GetMaxTag(isMessageSet bool) int32 { |
| 287 | if isMessageSet { |
| 288 | return MaxMessageSetTag |
| 289 | } |
| 290 | return MaxNormalTag |
| 291 | } |