github.com/cloudwego/kitex@v0.9.0/pkg/generic/thrift/parse.go (about) 1 /* 2 * Copyright 2021 CloudWeGo Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package thrift 18 19 import ( 20 "context" 21 "errors" 22 "fmt" 23 "runtime/debug" 24 25 "github.com/cloudwego/thriftgo/parser" 26 "github.com/cloudwego/thriftgo/semantic" 27 28 "github.com/cloudwego/kitex/pkg/generic/descriptor" 29 "github.com/cloudwego/kitex/pkg/gofunc" 30 "github.com/cloudwego/kitex/pkg/klog" 31 ) 32 33 const ( 34 initRecursionDepth = 0 35 ) 36 37 // ParseMode . 38 type ParseMode int 39 40 const ( 41 // LastServiceOnly forces the parser to parse only the last service definition. 42 LastServiceOnly ParseMode = iota 43 44 // FirstServiceOnly forces the parser to parse only the first service definition. 45 FirstServiceOnly 46 47 // CombineServices forces the parser to combine methods of all service definitions. 48 // Note that method names of the service definitions can not be duplicate. 49 CombineServices 50 ) 51 52 var defaultParseMode = LastServiceOnly 53 54 // DefaultParseMode returns the default parse mode. 55 func DefaultParseMode() ParseMode { 56 return defaultParseMode 57 } 58 59 // SetDefaultParseMode sets the default parse mode. 60 func SetDefaultParseMode(m ParseMode) { 61 defaultParseMode = m 62 } 63 64 // Parse descriptor from parser.Thrift 65 func Parse(tree *parser.Thrift, mode ParseMode) (*descriptor.ServiceDescriptor, error) { 66 if len(tree.Services) == 0 { 67 return nil, errors.New("empty serverce from idls") 68 } 69 if err := semantic.ResolveSymbols(tree); err != nil { 70 return nil, err 71 } 72 73 sDsc := &descriptor.ServiceDescriptor{ 74 Functions: map[string]*descriptor.FunctionDescriptor{}, 75 Router: descriptor.NewRouter(), 76 } 77 78 // support one service 79 svcs := tree.Services 80 switch mode { 81 case LastServiceOnly: 82 svcs = svcs[len(svcs)-1:] 83 sDsc.Name = svcs[len(svcs)-1].Name 84 case FirstServiceOnly: 85 svcs = svcs[:1] 86 sDsc.Name = svcs[0].Name 87 case CombineServices: 88 sDsc.Name = "CombinedServices" 89 } 90 91 visitedSvcs := make(map[*parser.Service]bool, len(tree.Services)) 92 for _, svc := range svcs { 93 for p := range getAllSvcs(svc, tree, visitedSvcs) { 94 svc := p.data.(*parser.Service) 95 structsCache := map[string]*descriptor.TypeDescriptor{} 96 for _, fn := range svc.Functions { 97 if err := addFunction(fn, p.tree, sDsc, structsCache); err != nil { 98 return nil, err 99 } 100 } 101 } 102 } 103 return sDsc, nil 104 } 105 106 type pair struct { 107 tree *parser.Thrift 108 data interface{} 109 } 110 111 func getAllSvcs(svc *parser.Service, tree *parser.Thrift, visitedSvcs map[*parser.Service]bool) chan *pair { 112 svcs := make(chan *pair) 113 addSvc := func(tree *parser.Thrift, svc *parser.Service) { 114 if exist := visitedSvcs[svc]; !exist { 115 svcs <- &pair{tree: tree, data: svc} 116 visitedSvcs[svc] = true 117 } 118 } 119 gofunc.GoFunc(context.Background(), func() { 120 addSvc(tree, svc) 121 for base := svc.Extends; base != ""; base = svc.Extends { 122 ref := svc.GetReference() 123 if ref != nil { 124 idx := ref.GetIndex() 125 base = ref.GetName() 126 tree = tree.Includes[idx].Reference 127 } 128 svc, _ = tree.GetService(base) 129 addSvc(tree, svc) 130 } 131 close(svcs) 132 }) 133 return svcs 134 } 135 136 func addFunction(fn *parser.Function, tree *parser.Thrift, sDsc *descriptor.ServiceDescriptor, structsCache map[string]*descriptor.TypeDescriptor) (err error) { 137 if sDsc.Functions[fn.Name] != nil { 138 return fmt.Errorf("duplicate method name: %s", fn.Name) 139 } 140 if len(fn.Arguments) == 0 { 141 return fmt.Errorf("empty arguments in function: %s", fn.Name) 142 } 143 // only support single argument 144 field := fn.Arguments[0] 145 req := &descriptor.TypeDescriptor{ 146 Type: descriptor.STRUCT, 147 Struct: &descriptor.StructDescriptor{ 148 FieldsByID: map[int32]*descriptor.FieldDescriptor{}, 149 FieldsByName: map[string]*descriptor.FieldDescriptor{}, 150 }, 151 } 152 var reqType *descriptor.TypeDescriptor 153 reqType, err = parseType(field.Type, tree, structsCache, initRecursionDepth) 154 if err != nil { 155 return err 156 } 157 hasRequestBase := false 158 if reqType.Type == descriptor.STRUCT { 159 for _, f := range reqType.Struct.FieldsByName { 160 if f.Type.IsRequestBase { 161 hasRequestBase = true 162 break 163 } 164 } 165 } 166 reqField := &descriptor.FieldDescriptor{ 167 Name: field.Name, 168 ID: field.ID, 169 Type: reqType, 170 } 171 req.Struct.FieldsByID[field.ID] = reqField 172 req.Struct.FieldsByName[field.Name] = reqField 173 // parse response filed 174 resp := &descriptor.TypeDescriptor{ 175 Type: descriptor.STRUCT, 176 Struct: &descriptor.StructDescriptor{ 177 FieldsByID: map[int32]*descriptor.FieldDescriptor{}, 178 FieldsByName: map[string]*descriptor.FieldDescriptor{}, 179 }, 180 } 181 var respType *descriptor.TypeDescriptor 182 respType, err = parseType(fn.FunctionType, tree, structsCache, initRecursionDepth) 183 if err != nil { 184 return err 185 } 186 respField := &descriptor.FieldDescriptor{ 187 Type: respType, 188 } 189 // response has no name or id 190 resp.Struct.FieldsByID[0] = respField 191 resp.Struct.FieldsByName[""] = respField 192 193 if len(fn.Throws) > 0 { 194 // only support single exception 195 field := fn.Throws[0] 196 var exceptionType *descriptor.TypeDescriptor 197 exceptionType, err = parseType(field.Type, tree, structsCache, initRecursionDepth) 198 if err != nil { 199 return err 200 } 201 exceptionField := &descriptor.FieldDescriptor{ 202 Name: field.Name, 203 ID: field.ID, 204 IsException: true, 205 Type: exceptionType, 206 } 207 resp.Struct.FieldsByID[field.ID] = exceptionField 208 resp.Struct.FieldsByName[field.Name] = exceptionField 209 } 210 fnDsc := &descriptor.FunctionDescriptor{ 211 Name: fn.Name, 212 Oneway: fn.Oneway, 213 Request: req, 214 Response: resp, 215 HasRequestBase: hasRequestBase, 216 } 217 defer func() { 218 if ret := recover(); ret != nil { 219 klog.Errorf("KITEX: router handle failed, err=%v\nstack=%s", ret, string(debug.Stack())) 220 err = fmt.Errorf("router handle failed, err=%v", ret) 221 } 222 }() 223 for _, ann := range fn.Annotations { 224 for _, v := range ann.GetValues() { 225 if handle, ok := descriptor.FindAnnotation(ann.GetKey(), v); ok { 226 if nr, ok := handle.(descriptor.NewRoute); ok { 227 sDsc.Router.Handle(nr(v, fnDsc)) 228 break 229 } 230 } 231 } 232 } 233 sDsc.Functions[fn.Name] = fnDsc 234 return nil 235 } 236 237 // reuse builtin types 238 var builtinTypes = map[string]*descriptor.TypeDescriptor{ 239 "void": {Name: "void", Type: descriptor.VOID, Struct: new(descriptor.StructDescriptor)}, 240 "bool": {Name: "bool", Type: descriptor.BOOL}, 241 "byte": {Name: "byte", Type: descriptor.BYTE}, 242 "i8": {Name: "i8", Type: descriptor.I08}, 243 "i16": {Name: "i16", Type: descriptor.I16}, 244 "i32": {Name: "i32", Type: descriptor.I32}, 245 "i64": {Name: "i64", Type: descriptor.I64}, 246 "double": {Name: "double", Type: descriptor.DOUBLE}, 247 "string": {Name: "string", Type: descriptor.STRING}, 248 "binary": {Name: "binary", Type: descriptor.STRING}, 249 } 250 251 // arg cache: 252 // only support self reference on the same file 253 // cross file self reference complicate matters 254 func parseType(t *parser.Type, tree *parser.Thrift, cache map[string]*descriptor.TypeDescriptor, recursionDepth int) (*descriptor.TypeDescriptor, error) { 255 if ty, ok := builtinTypes[t.Name]; ok { 256 return ty, nil 257 } 258 259 nextRecursionDepth := recursionDepth + 1 260 261 var err error 262 switch t.Name { 263 case "list": 264 ty := &descriptor.TypeDescriptor{Name: t.Name} 265 ty.Type = descriptor.LIST 266 ty.Elem, err = parseType(t.ValueType, tree, cache, nextRecursionDepth) 267 return ty, err 268 case "set": 269 ty := &descriptor.TypeDescriptor{Name: t.Name} 270 ty.Type = descriptor.SET 271 ty.Elem, err = parseType(t.ValueType, tree, cache, nextRecursionDepth) 272 return ty, err 273 case "map": 274 ty := &descriptor.TypeDescriptor{Name: t.Name} 275 ty.Type = descriptor.MAP 276 if ty.Key, err = parseType(t.KeyType, tree, cache, nextRecursionDepth); err != nil { 277 return nil, err 278 } 279 ty.Elem, err = parseType(t.ValueType, tree, cache, nextRecursionDepth) 280 return ty, err 281 default: 282 // check the cache 283 if ty, ok := cache[t.Name]; ok { 284 return ty, nil 285 } 286 typePkg, typeName := splitType(t.Name) 287 if typePkg != "" { 288 ref, ok := tree.GetReference(typePkg) 289 if !ok { 290 return nil, fmt.Errorf("miss reference: %s", typePkg) 291 } 292 tree = ref 293 // cross file reference need empty cache 294 cache = map[string]*descriptor.TypeDescriptor{} 295 } 296 if typDef, ok := tree.GetTypedef(typeName); ok { 297 return parseType(typDef.Type, tree, cache, nextRecursionDepth) 298 } 299 if _, ok := tree.GetEnum(typeName); ok { 300 return builtinTypes["i32"], nil 301 } 302 var st *parser.StructLike 303 var ok bool 304 st, ok = tree.GetUnion(typeName) 305 if !ok { 306 st, ok = tree.GetStruct(typeName) 307 } 308 if !ok { 309 st, ok = tree.GetException(typeName) 310 } 311 if !ok { 312 return nil, fmt.Errorf("missing type: %s", typeName) 313 } 314 ty := &descriptor.TypeDescriptor{ 315 Name: t.Name, 316 Type: descriptor.STRUCT, 317 Struct: &descriptor.StructDescriptor{ 318 Name: typeName, 319 FieldsByID: map[int32]*descriptor.FieldDescriptor{}, 320 FieldsByName: map[string]*descriptor.FieldDescriptor{}, 321 RequiredFields: map[int32]*descriptor.FieldDescriptor{}, 322 DefaultFields: map[string]*descriptor.FieldDescriptor{}, 323 }, 324 // the first depth of base.Base is Request Base 325 IsRequestBase: t.Name == "base.Base" && recursionDepth == 1, 326 } 327 // cannot cache the request base 328 if !ty.IsRequestBase { 329 cache[t.Name] = ty 330 } 331 for _, field := range st.Fields { 332 _f := &descriptor.FieldDescriptor{ 333 ID: field.ID, 334 Name: field.Name, 335 Required: field.Requiredness == parser.FieldType_Required, 336 Optional: field.Requiredness == parser.FieldType_Optional, 337 } 338 339 for _, ann := range field.Annotations { 340 for _, v := range ann.GetValues() { 341 if handle, ok := descriptor.FindAnnotation(ann.GetKey(), v); ok { 342 switch h := handle.(type) { 343 case descriptor.NewHTTPMapping: 344 _f.HTTPMapping = h(v) 345 case descriptor.NewValueMapping: 346 _f.ValueMapping = h(v) 347 case descriptor.NewFieldMapping: 348 // execute at compile time 349 h(v).Handle(_f) 350 case nil: 351 // none annotation 352 default: 353 // not supported annotation type 354 return nil, fmt.Errorf("not supported handle type: %T", handle) 355 } 356 } 357 } 358 } 359 if _f.HTTPMapping == nil { 360 _f.HTTPMapping = descriptor.DefaultNewMapping(_f.FieldName()) 361 } 362 if _f.Type, err = parseType(field.Type, tree, cache, nextRecursionDepth); err != nil { 363 return nil, err 364 } 365 // set default value 366 if field.IsSetDefault() { 367 _f.DefaultValue, err = parse(tree, field.Name, field.Type, field.Default) 368 if err != nil { 369 return nil, err 370 } 371 ty.Struct.DefaultFields[_f.FieldName()] = _f 372 } 373 ty.Struct.FieldsByID[field.ID] = _f 374 ty.Struct.FieldsByName[_f.FieldName()] = _f 375 if _f.Required { 376 ty.Struct.RequiredFields[field.ID] = _f 377 } 378 } 379 return ty, nil 380 } 381 } 382 383 func parse(tree *parser.Thrift, name string, t *parser.Type, v *parser.ConstValue) (interface{}, error) { 384 switch t.Category { 385 case parser.Category_Bool: 386 return onBool(tree, name, t, v) 387 case parser.Category_Byte: 388 val, err := onInt(tree, name, t, v) 389 if err != nil { 390 return nil, err 391 } 392 return byte(val), nil 393 case parser.Category_I16: 394 val, err := onInt(tree, name, t, v) 395 if err != nil { 396 return nil, err 397 } 398 return int16(val), nil 399 case parser.Category_I32: 400 val, err := onInt(tree, name, t, v) 401 if err != nil { 402 return nil, err 403 } 404 return int32(val), nil 405 case parser.Category_I64: 406 return onInt(tree, name, t, v) 407 case parser.Category_Double: 408 return onDouble(tree, name, t, v) 409 case parser.Category_String: 410 return onStr(tree, name, t, v) 411 case parser.Category_Binary: 412 str, err := onStr(tree, name, t, v) 413 if err != nil { 414 return nil, err 415 } 416 return []byte(str), nil 417 case parser.Category_Enum: 418 return onEnum(tree, name, t, v) 419 case parser.Category_Set, parser.Category_List: 420 return onSetOrList(tree, name, t, v) 421 case parser.Category_Map: 422 return onMap(tree, name, t, v) 423 case parser.Category_Struct, parser.Category_Union, parser.Category_Exception: 424 return onStructLike(tree, name, t, v) 425 } 426 return nil, fmt.Errorf("type error: '%s' was declared as type %s but got value[%v] of category[%s]", name, t, v, t.Category) 427 } 428 429 func onBool(tree *parser.Thrift, name string, t *parser.Type, v *parser.ConstValue) (bool, error) { 430 switch v.Type { 431 case parser.ConstType_ConstInt: 432 val := v.TypedValue.GetInt() 433 return val > 0, nil 434 case parser.ConstType_ConstDouble: 435 val := v.TypedValue.GetDouble() 436 return val > 0, nil 437 case parser.ConstType_ConstIdentifier: 438 s := v.TypedValue.GetIdentifier() 439 if s == "true" { 440 return true, nil 441 } 442 if s == "false" { 443 return false, nil 444 } 445 val, err := getIDValue(tree, name, t, v.Extra) 446 if err != nil { 447 return false, err 448 } 449 switch rv := val.(type) { 450 case bool: 451 return rv, nil 452 } 453 return false, fmt.Errorf("%s[%T] not match bool type", v.Extra.Name, val) 454 } 455 return false, fmt.Errorf("type error: '%s' was declared as type %s", name, t) 456 } 457 458 func onInt(tree *parser.Thrift, name string, t *parser.Type, v *parser.ConstValue) (int64, error) { 459 switch v.Type { 460 case parser.ConstType_ConstInt: 461 val := v.TypedValue.GetInt() 462 return val, nil 463 case parser.ConstType_ConstIdentifier: 464 s := v.TypedValue.GetIdentifier() 465 if s == "true" { 466 return 1, nil 467 } 468 if s == "false" { 469 return 0, nil 470 } 471 val, err := getIDValue(tree, name, t, v.Extra) 472 if err != nil { 473 return 0, err 474 } 475 switch rv := val.(type) { 476 case byte: 477 return int64(rv), nil 478 case int16: 479 return int64(rv), nil 480 case int32: 481 return int64(rv), nil 482 case int64: 483 return rv, nil 484 } 485 return 0, fmt.Errorf("%s[%T] not match int64 type", v.Extra.Name, val) 486 } 487 return 0, fmt.Errorf("type error: '%s' was declared as type %s", name, t) 488 } 489 490 func onDouble(tree *parser.Thrift, name string, t *parser.Type, v *parser.ConstValue) (float64, error) { 491 switch v.Type { 492 case parser.ConstType_ConstInt: 493 val := v.TypedValue.GetInt() 494 return float64(val), nil 495 case parser.ConstType_ConstDouble: 496 val := v.TypedValue.GetDouble() 497 return val, nil 498 case parser.ConstType_ConstIdentifier: 499 s := v.TypedValue.GetIdentifier() 500 if s == "true" { 501 return 1.0, nil 502 } 503 if s == "false" { 504 return 0.0, nil 505 } 506 val, err := getIDValue(tree, name, t, v.Extra) 507 if err != nil { 508 return 0, err 509 } 510 switch rv := val.(type) { 511 case float64: 512 return rv, nil 513 case int64: 514 return float64(rv), nil 515 } 516 return 0, fmt.Errorf("%s[%T] not match float64 type", v.Extra.Name, val) 517 } 518 return 0, fmt.Errorf("type error: '%s' was declared as type %s", name, t) 519 } 520 521 func onStr(tree *parser.Thrift, name string, t *parser.Type, v *parser.ConstValue) (string, error) { 522 switch v.Type { 523 case parser.ConstType_ConstLiteral: 524 return v.TypedValue.GetLiteral(), nil 525 case parser.ConstType_ConstIdentifier: 526 s := v.TypedValue.GetIdentifier() 527 if s == "true" || s == "false" { 528 break 529 } 530 val, err := getIDValue(tree, name, t, v.Extra) 531 if err != nil { 532 return "", err 533 } 534 switch rv := val.(type) { 535 case string: 536 return rv, nil 537 } 538 return "", fmt.Errorf("%s[%T] not match string type", v.Extra.Name, val) 539 } 540 return "", fmt.Errorf("type error: '%s' was declared as type %s", name, t) 541 } 542 543 func onEnum(tree *parser.Thrift, name string, t *parser.Type, v *parser.ConstValue) (int64, error) { 544 switch v.Type { 545 case parser.ConstType_ConstInt: 546 return v.TypedValue.GetInt(), nil 547 case parser.ConstType_ConstIdentifier: 548 val, err := getIDValue(tree, name, t, v.Extra) 549 if err != nil { 550 return 0, err 551 } 552 switch rv := val.(type) { 553 case int64: 554 return rv, nil 555 } 556 return 0, fmt.Errorf("%s[%T] not match int64 type", v.Extra.Name, val) 557 } 558 return 0, fmt.Errorf("expect const value for %q is a int or enum, got %+v", name, v) 559 } 560 561 func onSetOrList(tree *parser.Thrift, name string, t *parser.Type, v *parser.ConstValue) (res []interface{}, err error) { 562 switch v.Type { 563 case parser.ConstType_ConstList: 564 elemName := "element of " + name 565 for _, elem := range v.TypedValue.GetList() { 566 val, err := parse(tree, elemName, t.ValueType, elem) 567 if err != nil { 568 return nil, err 569 } 570 res = append(res, val) 571 } 572 return res, nil 573 case parser.ConstType_ConstIdentifier: 574 val, err := getIDValue(tree, name, t, v.Extra) 575 if err != nil { 576 return nil, err 577 } 578 switch rv := val.(type) { 579 case []interface{}: 580 return rv, nil 581 } 582 return nil, fmt.Errorf("%s[%T] not match []interface{} type", v.Extra.Name, val) 583 } 584 // fault tolerance 585 return 586 } 587 588 func onMap(tree *parser.Thrift, name string, t *parser.Type, v *parser.ConstValue) (res map[interface{}]interface{}, err error) { 589 res = make(map[interface{}]interface{}) 590 switch v.Type { 591 case parser.ConstType_ConstMap: 592 for _, mcv := range v.TypedValue.Map { 593 keyName := "key of " + name 594 key, err := parse(tree, keyName, bin2str(t.KeyType), mcv.Key) 595 if err != nil { 596 return nil, err 597 } 598 valName := "value of " + name 599 val, err := parse(tree, valName, t.ValueType, mcv.Value) 600 if err != nil { 601 return nil, err 602 } 603 res[key] = val 604 } 605 return res, nil 606 607 case parser.ConstType_ConstIdentifier: 608 val, err := getIDValue(tree, name, t, v.Extra) 609 if err != nil { 610 return nil, err 611 } 612 switch rv := val.(type) { 613 case map[interface{}]interface{}: 614 return rv, nil 615 } 616 return nil, fmt.Errorf("%s[%T] not match map[interface{}]interface{} type", v.Extra.Name, val) 617 } 618 // fault tolerance 619 return 620 } 621 622 func onStructLike(tree *parser.Thrift, name string, t *parser.Type, v *parser.ConstValue) (res map[string]interface{}, err error) { 623 if v.Type == parser.ConstType_ConstIdentifier { 624 val, err := getIDValue(tree, name, t, v.Extra) 625 if err != nil { 626 return nil, err 627 } 628 switch rv := val.(type) { 629 case map[string]interface{}: 630 return rv, nil 631 } 632 return nil, fmt.Errorf("%s[%T] not match map[string]interface{} type", v.Extra.Name, val) 633 } 634 635 if v.Type != parser.ConstType_ConstMap { 636 // constant value of a struct-like must be a map literal 637 return nil, fmt.Errorf("type error: '%s' was declared as type %s", name, t) 638 } 639 640 // get the target struct-like with typedef dereferenced 641 file, st, err := getStructLike(tree, t) 642 if err != nil { 643 return nil, err 644 } 645 646 res = make(map[string]interface{}) 647 for _, mcv := range v.TypedValue.Map { 648 if mcv.Key.Type != parser.ConstType_ConstLiteral { 649 return nil, fmt.Errorf("expect literals as keys in default value of struct type '%s', got '%s'", name, mcv.Key.Type) 650 } 651 n := mcv.Key.TypedValue.GetLiteral() 652 653 f, ok := st.GetField(n) 654 if !ok { 655 return nil, fmt.Errorf("field %q not found in %q (%q): %v", 656 n, st.Name, file.Filename, v, 657 ) 658 } 659 val, err := parse(file, st.Name+"."+f.Name, f.Type, mcv.Value) 660 if err != nil { 661 return nil, err 662 } 663 res[n] = val 664 } 665 666 return res, nil 667 } 668 669 func getStructLike(tree *parser.Thrift, t *parser.Type) (ast *parser.Thrift, s *parser.StructLike, err error) { 670 var x *parser.Type 671 ast, x, err = semantic.Deref(tree, t) 672 if err != nil { 673 err = fmt.Errorf("expect %q a typedef or struct-like in %q: %w", 674 t.Name, tree.Filename, err) 675 return nil, nil, err 676 } 677 for _, y := range ast.GetStructLikes() { 678 if x.Name == y.Name { 679 s = y 680 } 681 } 682 if s == nil { 683 err = fmt.Errorf("expect %q a struct-like in %q: not found: %v", 684 x.Name, ast.Filename, x == t) 685 return nil, nil, err 686 } 687 return 688 } 689 690 func getIDValue(tree *parser.Thrift, name string, t *parser.Type, extra *parser.ConstValueExtra) (interface{}, error) { 691 if extra.Index == -1 { 692 if extra.IsEnum { 693 enum, ok := tree.GetEnum(extra.Sel) 694 if !ok { 695 return nil, fmt.Errorf("no matching enum of %s", extra.Sel) 696 } 697 for _, v := range enum.Values { 698 if v.Name == extra.Name { 699 return v.Value, nil 700 } 701 } 702 } else { 703 if con, ok := tree.GetConstant(extra.Name); ok { 704 return parse(tree, name, con.Type, con.Value) 705 } 706 } 707 } else { 708 tree = tree.Includes[extra.Index].Reference 709 extra = &parser.ConstValueExtra{ 710 Index: -1, 711 IsEnum: extra.IsEnum, 712 Name: extra.Name, 713 Sel: extra.Sel, 714 } 715 return getIDValue(tree, name, t, extra) 716 } 717 return nil, fmt.Errorf("undefined value %s", extra.Name) 718 } 719 720 func bin2str(t *parser.Type) *parser.Type { 721 if t.Category == parser.Category_Binary { 722 r := *t 723 r.Category = parser.Category_String 724 return &r 725 } 726 return t 727 }