github.com/gogo/protobuf@v1.3.2/protoc-gen-gogo/descriptor/helper.go (about) 1 // Protocol Buffers for Go with Gadgets 2 // 3 // Copyright (c) 2013, The GoGo Authors. All rights reserved. 4 // http://github.com/gogo/protobuf 5 // 6 // Redistribution and use in source and binary forms, with or without 7 // modification, are permitted provided that the following conditions are 8 // met: 9 // 10 // * Redistributions of source code must retain the above copyright 11 // notice, this list of conditions and the following disclaimer. 12 // * Redistributions in binary form must reproduce the above 13 // copyright notice, this list of conditions and the following disclaimer 14 // in the documentation and/or other materials provided with the 15 // distribution. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 package descriptor 30 31 import ( 32 "strings" 33 ) 34 35 func (msg *DescriptorProto) GetMapFields() (*FieldDescriptorProto, *FieldDescriptorProto) { 36 if !msg.GetOptions().GetMapEntry() { 37 return nil, nil 38 } 39 return msg.GetField()[0], msg.GetField()[1] 40 } 41 42 func dotToUnderscore(r rune) rune { 43 if r == '.' { 44 return '_' 45 } 46 return r 47 } 48 49 func (field *FieldDescriptorProto) WireType() (wire int) { 50 switch *field.Type { 51 case FieldDescriptorProto_TYPE_DOUBLE: 52 return 1 53 case FieldDescriptorProto_TYPE_FLOAT: 54 return 5 55 case FieldDescriptorProto_TYPE_INT64: 56 return 0 57 case FieldDescriptorProto_TYPE_UINT64: 58 return 0 59 case FieldDescriptorProto_TYPE_INT32: 60 return 0 61 case FieldDescriptorProto_TYPE_UINT32: 62 return 0 63 case FieldDescriptorProto_TYPE_FIXED64: 64 return 1 65 case FieldDescriptorProto_TYPE_FIXED32: 66 return 5 67 case FieldDescriptorProto_TYPE_BOOL: 68 return 0 69 case FieldDescriptorProto_TYPE_STRING: 70 return 2 71 case FieldDescriptorProto_TYPE_GROUP: 72 return 2 73 case FieldDescriptorProto_TYPE_MESSAGE: 74 return 2 75 case FieldDescriptorProto_TYPE_BYTES: 76 return 2 77 case FieldDescriptorProto_TYPE_ENUM: 78 return 0 79 case FieldDescriptorProto_TYPE_SFIXED32: 80 return 5 81 case FieldDescriptorProto_TYPE_SFIXED64: 82 return 1 83 case FieldDescriptorProto_TYPE_SINT32: 84 return 0 85 case FieldDescriptorProto_TYPE_SINT64: 86 return 0 87 } 88 panic("unreachable") 89 } 90 91 func (field *FieldDescriptorProto) GetKeyUint64() (x uint64) { 92 packed := field.IsPacked() 93 wireType := field.WireType() 94 fieldNumber := field.GetNumber() 95 if packed { 96 wireType = 2 97 } 98 x = uint64(uint32(fieldNumber)<<3 | uint32(wireType)) 99 return x 100 } 101 102 func (field *FieldDescriptorProto) GetKey3Uint64() (x uint64) { 103 packed := field.IsPacked3() 104 wireType := field.WireType() 105 fieldNumber := field.GetNumber() 106 if packed { 107 wireType = 2 108 } 109 x = uint64(uint32(fieldNumber)<<3 | uint32(wireType)) 110 return x 111 } 112 113 func (field *FieldDescriptorProto) GetKey() []byte { 114 x := field.GetKeyUint64() 115 i := 0 116 keybuf := make([]byte, 0) 117 for i = 0; x > 127; i++ { 118 keybuf = append(keybuf, 0x80|uint8(x&0x7F)) 119 x >>= 7 120 } 121 keybuf = append(keybuf, uint8(x)) 122 return keybuf 123 } 124 125 func (field *FieldDescriptorProto) GetKey3() []byte { 126 x := field.GetKey3Uint64() 127 i := 0 128 keybuf := make([]byte, 0) 129 for i = 0; x > 127; i++ { 130 keybuf = append(keybuf, 0x80|uint8(x&0x7F)) 131 x >>= 7 132 } 133 keybuf = append(keybuf, uint8(x)) 134 return keybuf 135 } 136 137 func (desc *FileDescriptorSet) GetField(packageName, messageName, fieldName string) *FieldDescriptorProto { 138 msg := desc.GetMessage(packageName, messageName) 139 if msg == nil { 140 return nil 141 } 142 for _, field := range msg.GetField() { 143 if field.GetName() == fieldName { 144 return field 145 } 146 } 147 return nil 148 } 149 150 func (file *FileDescriptorProto) GetMessage(typeName string) *DescriptorProto { 151 for _, msg := range file.GetMessageType() { 152 if msg.GetName() == typeName { 153 return msg 154 } 155 nes := file.GetNestedMessage(msg, strings.TrimPrefix(typeName, msg.GetName()+".")) 156 if nes != nil { 157 return nes 158 } 159 } 160 return nil 161 } 162 163 func (file *FileDescriptorProto) GetNestedMessage(msg *DescriptorProto, typeName string) *DescriptorProto { 164 for _, nes := range msg.GetNestedType() { 165 if nes.GetName() == typeName { 166 return nes 167 } 168 res := file.GetNestedMessage(nes, strings.TrimPrefix(typeName, nes.GetName()+".")) 169 if res != nil { 170 return res 171 } 172 } 173 return nil 174 } 175 176 func (desc *FileDescriptorSet) GetMessage(packageName string, typeName string) *DescriptorProto { 177 for _, file := range desc.GetFile() { 178 if strings.Map(dotToUnderscore, file.GetPackage()) != strings.Map(dotToUnderscore, packageName) { 179 continue 180 } 181 for _, msg := range file.GetMessageType() { 182 if msg.GetName() == typeName { 183 return msg 184 } 185 } 186 for _, msg := range file.GetMessageType() { 187 for _, nes := range msg.GetNestedType() { 188 if nes.GetName() == typeName { 189 return nes 190 } 191 if msg.GetName()+"."+nes.GetName() == typeName { 192 return nes 193 } 194 } 195 } 196 } 197 return nil 198 } 199 200 func (desc *FileDescriptorSet) IsProto3(packageName string, typeName string) bool { 201 for _, file := range desc.GetFile() { 202 if strings.Map(dotToUnderscore, file.GetPackage()) != strings.Map(dotToUnderscore, packageName) { 203 continue 204 } 205 for _, msg := range file.GetMessageType() { 206 if msg.GetName() == typeName { 207 return file.GetSyntax() == "proto3" 208 } 209 } 210 for _, msg := range file.GetMessageType() { 211 for _, nes := range msg.GetNestedType() { 212 if nes.GetName() == typeName { 213 return file.GetSyntax() == "proto3" 214 } 215 if msg.GetName()+"."+nes.GetName() == typeName { 216 return file.GetSyntax() == "proto3" 217 } 218 } 219 } 220 } 221 return false 222 } 223 224 func (msg *DescriptorProto) IsExtendable() bool { 225 return len(msg.GetExtensionRange()) > 0 226 } 227 228 func (desc *FileDescriptorSet) FindExtension(packageName string, typeName string, fieldName string) (extPackageName string, field *FieldDescriptorProto) { 229 parent := desc.GetMessage(packageName, typeName) 230 if parent == nil { 231 return "", nil 232 } 233 if !parent.IsExtendable() { 234 return "", nil 235 } 236 extendee := "." + packageName + "." + typeName 237 for _, file := range desc.GetFile() { 238 for _, ext := range file.GetExtension() { 239 if strings.Map(dotToUnderscore, file.GetPackage()) == strings.Map(dotToUnderscore, packageName) { 240 if !(ext.GetExtendee() == typeName || ext.GetExtendee() == extendee) { 241 continue 242 } 243 } else { 244 if ext.GetExtendee() != extendee { 245 continue 246 } 247 } 248 if ext.GetName() == fieldName { 249 return file.GetPackage(), ext 250 } 251 } 252 } 253 return "", nil 254 } 255 256 func (desc *FileDescriptorSet) FindExtensionByFieldNumber(packageName string, typeName string, fieldNum int32) (extPackageName string, field *FieldDescriptorProto) { 257 parent := desc.GetMessage(packageName, typeName) 258 if parent == nil { 259 return "", nil 260 } 261 if !parent.IsExtendable() { 262 return "", nil 263 } 264 extendee := "." + packageName + "." + typeName 265 for _, file := range desc.GetFile() { 266 for _, ext := range file.GetExtension() { 267 if strings.Map(dotToUnderscore, file.GetPackage()) == strings.Map(dotToUnderscore, packageName) { 268 if !(ext.GetExtendee() == typeName || ext.GetExtendee() == extendee) { 269 continue 270 } 271 } else { 272 if ext.GetExtendee() != extendee { 273 continue 274 } 275 } 276 if ext.GetNumber() == fieldNum { 277 return file.GetPackage(), ext 278 } 279 } 280 } 281 return "", nil 282 } 283 284 func (desc *FileDescriptorSet) FindMessage(packageName string, typeName string, fieldName string) (msgPackageName string, msgName string) { 285 parent := desc.GetMessage(packageName, typeName) 286 if parent == nil { 287 return "", "" 288 } 289 field := parent.GetFieldDescriptor(fieldName) 290 if field == nil { 291 var extPackageName string 292 extPackageName, field = desc.FindExtension(packageName, typeName, fieldName) 293 if field == nil { 294 return "", "" 295 } 296 packageName = extPackageName 297 } 298 typeNames := strings.Split(field.GetTypeName(), ".") 299 if len(typeNames) == 1 { 300 msg := desc.GetMessage(packageName, typeName) 301 if msg == nil { 302 return "", "" 303 } 304 return packageName, msg.GetName() 305 } 306 if len(typeNames) > 2 { 307 for i := 1; i < len(typeNames)-1; i++ { 308 packageName = strings.Join(typeNames[1:len(typeNames)-i], ".") 309 typeName = strings.Join(typeNames[len(typeNames)-i:], ".") 310 msg := desc.GetMessage(packageName, typeName) 311 if msg != nil { 312 typeNames := strings.Split(msg.GetName(), ".") 313 if len(typeNames) == 1 { 314 return packageName, msg.GetName() 315 } 316 return strings.Join(typeNames[1:len(typeNames)-1], "."), typeNames[len(typeNames)-1] 317 } 318 } 319 } 320 return "", "" 321 } 322 323 func (msg *DescriptorProto) GetFieldDescriptor(fieldName string) *FieldDescriptorProto { 324 for _, field := range msg.GetField() { 325 if field.GetName() == fieldName { 326 return field 327 } 328 } 329 return nil 330 } 331 332 func (desc *FileDescriptorSet) GetEnum(packageName string, typeName string) *EnumDescriptorProto { 333 for _, file := range desc.GetFile() { 334 if strings.Map(dotToUnderscore, file.GetPackage()) != strings.Map(dotToUnderscore, packageName) { 335 continue 336 } 337 for _, enum := range file.GetEnumType() { 338 if enum.GetName() == typeName { 339 return enum 340 } 341 } 342 } 343 return nil 344 } 345 346 func (f *FieldDescriptorProto) IsEnum() bool { 347 return *f.Type == FieldDescriptorProto_TYPE_ENUM 348 } 349 350 func (f *FieldDescriptorProto) IsMessage() bool { 351 return *f.Type == FieldDescriptorProto_TYPE_MESSAGE 352 } 353 354 func (f *FieldDescriptorProto) IsBytes() bool { 355 return *f.Type == FieldDescriptorProto_TYPE_BYTES 356 } 357 358 func (f *FieldDescriptorProto) IsRepeated() bool { 359 return f.Label != nil && *f.Label == FieldDescriptorProto_LABEL_REPEATED 360 } 361 362 func (f *FieldDescriptorProto) IsString() bool { 363 return *f.Type == FieldDescriptorProto_TYPE_STRING 364 } 365 366 func (f *FieldDescriptorProto) IsBool() bool { 367 return *f.Type == FieldDescriptorProto_TYPE_BOOL 368 } 369 370 func (f *FieldDescriptorProto) IsRequired() bool { 371 return f.Label != nil && *f.Label == FieldDescriptorProto_LABEL_REQUIRED 372 } 373 374 func (f *FieldDescriptorProto) IsPacked() bool { 375 return f.Options != nil && f.GetOptions().GetPacked() 376 } 377 378 func (f *FieldDescriptorProto) IsPacked3() bool { 379 if f.IsRepeated() && f.IsScalar() { 380 if f.Options == nil || f.GetOptions().Packed == nil { 381 return true 382 } 383 return f.Options != nil && f.GetOptions().GetPacked() 384 } 385 return false 386 } 387 388 func (m *DescriptorProto) HasExtension() bool { 389 return len(m.ExtensionRange) > 0 390 }