github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/proto/generic/node.go (about) 1 package generic 2 3 import ( 4 "fmt" 5 "unsafe" 6 7 "github.com/cloudwego/dynamicgo/internal/rt" 8 "github.com/cloudwego/dynamicgo/meta" 9 "github.com/cloudwego/dynamicgo/proto" 10 "github.com/cloudwego/dynamicgo/proto/binary" 11 "github.com/cloudwego/dynamicgo/proto/protowire" 12 ) 13 14 type Node struct { 15 t proto.Type 16 et proto.Type 17 kt proto.Type 18 v unsafe.Pointer 19 l int 20 size int // only for MAP/LIST element counts 21 } 22 23 // Fork forks the node to a new node, copy underlying data as well 24 func (self Node) Fork() Node { 25 ret := self 26 buf := make([]byte, self.l, self.l) 27 copy(buf, rt.BytesFrom(self.v, self.l, self.l)) 28 ret.v = rt.GetBytePtr(buf) 29 return ret 30 } 31 32 // Type returns the proto type of the node 33 func (self Node) Type() proto.Type { 34 return self.t 35 } 36 37 // ElemType returns the thrift type of a LIST/MAP node's element 38 func (self Node) ElemType() proto.Type { 39 return self.et 40 } 41 42 // KeyType returns the thrift type of a MAP node's key 43 func (self Node) KeyType() proto.Type { 44 return self.kt 45 } 46 47 // slice returns a new node which is a slice of a simple node 48 func (self Node) slice(s int, e int, t proto.Type) Node { 49 ret := Node{ 50 t: t, 51 l: (e - s), 52 v: rt.AddPtr(self.v, uintptr(s)), 53 } 54 return ret 55 } 56 57 // sliceComplex returns a new node which is a slice of a Complex(can deal with all the type) node 58 func (self Node) sliceComplex(s int, e int, t proto.Type, kt proto.Type, et proto.Type, size int) Node { 59 ret := Node{ 60 t: t, 61 l: (e - s), 62 v: rt.AddPtr(self.v, uintptr(s)), 63 } 64 if t == proto.LIST { 65 ret.et = et 66 ret.size = size 67 } else if t == proto.MAP { 68 ret.kt = kt 69 ret.et = et 70 ret.size = size 71 } 72 return ret 73 } 74 75 func (self Node) sliceNodeWithDesc(s int, e int, desc *proto.TypeDescriptor) Node { 76 t := desc.Type() 77 ret := Node{ 78 t: t, 79 l: (e - s), 80 v: rt.AddPtr(self.v, uintptr(s)), 81 } 82 if t == proto.LIST { 83 ret.et = desc.Elem().Type() 84 } else if t == proto.MAP { 85 ret.kt = desc.Key().Type() 86 ret.et = desc.Elem().Type() 87 } 88 return ret 89 } 90 91 func (self Node) offset() unsafe.Pointer { 92 return rt.AddPtr(self.v, uintptr(self.l)) 93 } 94 95 func (self *Node) SetElemType(et proto.Type) { 96 self.et = et 97 } 98 99 func (self *Node) SetKeyType(kt proto.Type) { 100 self.kt = kt 101 } 102 103 func (self *Node) replace(o Node, n Node) error { 104 // mush ensure target value is same type as source value 105 if o.t != n.t { 106 return wrapError(meta.ErrDismatchType, fmt.Sprintf("type mismatch: %s != %s", o.t, n.t), nil) 107 } 108 // export target node to bytes 109 pat := n.raw() 110 111 // divide self's buffer into three slices: 112 // 1. self's slice before the target node 113 // 2. target node's slice 114 // 3. self's slice after the target node 115 s1 := rt.AddPtr(o.v, uintptr(o.l)) 116 l0 := int(uintptr(o.v) - uintptr(self.v)) 117 l1 := len(pat) 118 l2 := int(uintptr(self.v) + uintptr(self.l) - uintptr(s1)) 119 120 // copy three slices into new buffer 121 buf := make([]byte, l0+l1+l2) 122 copy(buf[:l0], rt.BytesFrom(self.v, l0, l0)) 123 copy(buf[l0:l0+l1], pat) 124 copy(buf[l0+l1:l0+l1+l2], rt.BytesFrom(s1, l2, l2)) 125 126 // replace self's entire buffer 127 self.v = rt.GetBytePtr(buf) 128 self.l = int(len(buf)) 129 return nil 130 } 131 132 // have problem in deal with byteLength 133 func (o *Node) setNotFound(path Path, n *Node, desc *proto.TypeDescriptor) error { 134 switch o.kt { 135 case proto.MESSAGE: 136 tag := path.ToRaw(n.t) 137 src := n.raw() 138 buf := make([]byte, 0, len(tag)+len(src)) 139 buf = append(buf, tag...) 140 buf = append(buf, src...) 141 n.l = len(buf) 142 n.v = rt.GetBytePtr(buf) 143 case proto.LIST: 144 // unpacked need write tag, packed needn't 145 if desc.IsPacked() == false { 146 fdNum := desc.BaseId() 147 tag := protowire.AppendVarint(nil, uint64(fdNum)<<3|uint64(proto.BytesType)) 148 src := n.raw() 149 buf := make([]byte, 0, len(tag)+len(src)) 150 buf = append(buf, tag...) 151 buf = append(buf, src...) 152 n.l = len(buf) 153 n.v = rt.GetBytePtr(buf) 154 } 155 case proto.MAP: 156 // pair tag 157 fdNum := desc.BaseId() 158 pairTag := protowire.AppendVarint(nil, uint64(fdNum)<<3|uint64(proto.BytesType)) 159 buf := path.ToRaw(n.t) // keytag + key 160 valueWireType := desc.Elem().WireType() 161 valueTag := uint64(1)<<3 | uint64(valueWireType) 162 buf = protowire.BinaryEncoder{}.EncodeUint64(buf, valueTag) // + value tag 163 src := n.raw() // + value 164 buf = append(buf, src...) // key + value 165 pairbuf := protowire.BinaryEncoder{}.EncodeUint64(pairTag, uint64(len(buf))) // + pairlen 166 pairbuf = append(pairbuf, buf...) // pair tag + pairlen + key + value 167 n.l = len(pairbuf) 168 n.v = rt.GetBytePtr(pairbuf) 169 default: 170 return wrapError(meta.ErrDismatchType, "simple type node shouldn't have child", nil) 171 } 172 o.t = n.t 173 o.l = 0 174 return nil 175 } 176 177 func (self *Node) replaceMany(ps *pnSlice) error { 178 var buf []byte 179 // Sort pathes by original value address 180 ps.Sort() 181 182 // sequentially set new values into buffer according to sorted pathes 183 buf = make([]byte, 0, self.l) 184 last := self.v 185 for i := 0; i < len(ps.a); i++ { 186 lastLen := rt.PtrOffset(ps.a[i].Node.v, last) 187 // copy last slice from original buffer 188 buf = append(buf, rt.BytesFrom(last, lastLen, lastLen)...) 189 // copy new value's buffer into buffer 190 buf = append(buf, ps.b[i].Node.raw()...) 191 // update last index 192 last = ps.a[i].offset() 193 } 194 if tail := self.offset(); uintptr(last) < uintptr(tail) { 195 // copy last slice from original buffer 196 buf = append(buf, rt.BytesFrom(last, rt.PtrOffset(tail, last), rt.PtrOffset(tail, last))...) 197 } 198 199 self.v = rt.GetBytePtr(buf) 200 self.l = int(len(buf)) 201 return nil 202 } 203 204 // NewNode method: creates a new node from a byte slice 205 func NewNode(t proto.Type, src []byte) Node { 206 ret := Node{ 207 t: t, 208 l: (len(src)), 209 v: rt.GetBytePtr(src), 210 } 211 return ret 212 } 213 214 func NewNodeBool(val bool) Node { 215 buf := make([]byte, 0, 1) 216 buf = protowire.BinaryEncoder{}.EncodeBool(buf, val) 217 return NewNode(proto.BOOL, buf) 218 } 219 220 func NewNodeByte(val byte) Node { 221 buf := make([]byte, 0, 1) 222 buf = protowire.BinaryEncoder{}.EncodeByte(buf, val) 223 return NewNode(proto.BYTE, buf) 224 } 225 226 func NewNodeEnum(val int32) Node { 227 buf := make([]byte, 0, 4) 228 buf = protowire.BinaryEncoder{}.EncodeEnum(buf, val) 229 return NewNode(proto.ENUM, buf) 230 } 231 232 func NewNodeInt32(val int32) Node { 233 buf := make([]byte, 0, 4) 234 buf = protowire.BinaryEncoder{}.EncodeInt32(buf, val) 235 return NewNode(proto.INT32, buf) 236 } 237 238 func NewNodeSint32(val int32) Node { 239 buf := make([]byte, 0, 4) 240 buf = protowire.BinaryEncoder{}.EncodeSint32(buf, val) 241 return NewNode(proto.SINT32, buf) 242 } 243 244 func NewNodeUint32(val uint32) Node { 245 buf := make([]byte, 0, 4) 246 buf = protowire.BinaryEncoder{}.EncodeUint32(buf, val) 247 return NewNode(proto.UINT32, buf) 248 } 249 250 func NewNodeFixed32(val uint32) Node { 251 buf := make([]byte, 0, 4) 252 buf = protowire.BinaryEncoder{}.EncodeFixed32(buf, val) 253 return NewNode(proto.FIX32, buf) 254 } 255 256 func NewNodeSfixed32(val int32) Node { 257 buf := make([]byte, 0, 4) 258 buf = protowire.BinaryEncoder{}.EncodeSfixed32(buf, val) 259 return NewNode(proto.SFIX32, buf) 260 } 261 262 func NewNodeInt64(val int64) Node { 263 buf := make([]byte, 0, 8) 264 buf = protowire.BinaryEncoder{}.EncodeInt64(buf, val) 265 return NewNode(proto.INT64, buf) 266 } 267 268 func NewNodeSint64(val int64) Node { 269 buf := make([]byte, 0, 8) 270 buf = protowire.BinaryEncoder{}.EncodeSint64(buf, val) 271 return NewNode(proto.SINT64, buf) 272 } 273 274 func NewNodeUint64(val uint64) Node { 275 buf := make([]byte, 0, 8) 276 buf = protowire.BinaryEncoder{}.EncodeUint64(buf, val) 277 return NewNode(proto.UINT64, buf) 278 } 279 280 func NewNodeFixed64(val uint64) Node { 281 buf := make([]byte, 0, 8) 282 buf = protowire.BinaryEncoder{}.EncodeFixed64(buf, val) 283 return NewNode(proto.FIX64, buf) 284 } 285 286 func NewNodeSfixed64(val int64) Node { 287 buf := make([]byte, 0, 8) 288 buf = protowire.BinaryEncoder{}.EncodeSfixed64(buf, val) 289 return NewNode(proto.SFIX64, buf) 290 } 291 292 func NewNodeFloat(val float32) Node { 293 buf := make([]byte, 0, 4) 294 buf = protowire.BinaryEncoder{}.EncodeFloat32(buf, val) 295 return NewNode(proto.FLOAT, buf) 296 } 297 298 func NewNodeDouble(val float64) Node { 299 buf := make([]byte, 0, 8) 300 buf = protowire.BinaryEncoder{}.EncodeDouble(buf, val) 301 return NewNode(proto.DOUBLE, buf) 302 } 303 304 func NewNodeString(val string) Node { 305 buf := make([]byte, 0, len(val)+4) 306 buf = protowire.BinaryEncoder{}.EncodeString(buf, val) 307 return NewNode(proto.STRING, buf) 308 } 309 310 func NewNodeBytes(val []byte) Node { 311 buf := make([]byte, 0, len(val)+4) 312 buf = protowire.BinaryEncoder{}.EncodeBytes(buf, val) 313 return NewNode(proto.BYTE, buf) 314 } 315 316 // NewComplexNode can deal with all the types, only if the src is a valid byte slice 317 func NewComplexNode(t proto.Type, et proto.Type, kt proto.Type, src []byte) (ret Node) { 318 if !t.Valid() { 319 panic("invalid node type") 320 } 321 ret = Node{ 322 t: t, 323 l: (len(src)), 324 v: rt.GetBytePtr(src), 325 } 326 327 switch t { 328 case proto.LIST: 329 if !et.Valid() { 330 panic("invalid element type") 331 } 332 ret.et = et 333 case proto.MAP: 334 if !et.Valid() { 335 panic("invalid element type") 336 } 337 if !kt.Valid() { 338 panic("invalid key type") 339 } 340 ret.et = et 341 ret.kt = kt 342 } 343 344 return 345 } 346 347 // returns all the children of a node, when recurse is false, it switch to lazyload mode, only direct children are returned 348 func (self Node) Children(out *[]PathNode, recurse bool, opts *Options, desc *proto.TypeDescriptor) (err error) { 349 if self.Error() != "" { 350 return self 351 } 352 353 if out == nil { 354 panic("out is nil") 355 } 356 // NOTICE: since we only use out for memory reuse, we always reset it to zero. 357 p := binary.BinaryProtocol{ 358 Buf: self.raw(), 359 } 360 361 tree := PathNode{ 362 Node: self, 363 Next: (*out)[:0], // NOTICE: we reset it to zero. 364 } 365 err = tree.scanChildren(&p, recurse, opts, desc, len(p.Buf)) 366 if err == nil { 367 *out = tree.Next 368 } 369 return err 370 } 371 372 // Get idx element of a LIST node 373 func (self Node) Index(idx int) (v Node) { 374 if err := self.should("Index", proto.LIST); err != "" { 375 return errNode(meta.ErrUnsupportedType, err, nil) 376 } 377 378 var s, e int 379 it := self.iterElems() 380 if it.Err != nil { 381 return errNode(meta.ErrRead, "", it.Err) 382 } 383 isPacked := it.IsPacked() 384 385 // size = 0 maybe list node is in lazyload mode, need to check idx with it.k 386 if it.size > 0 && idx >= it.size { 387 return errNode(meta.ErrInvalidParam, fmt.Sprintf("index %d exceeds list/set bound", idx), nil) 388 } 389 390 // read packed list tag and bytelen 391 if isPacked { 392 if _, _, _, err := it.p.ConsumeTag(); err != nil { 393 return errNode(meta.ErrRead, "", err) 394 } 395 if _, err := it.p.ReadLength(); err != nil { 396 return errNode(meta.ErrRead, "", err) 397 } 398 } 399 400 for j := 0; it.HasNext() && j < idx; j++ { 401 it.Next(UseNativeSkipForGet) 402 } 403 404 if it.Err != nil { 405 return errNode(meta.ErrRead, "", it.Err) 406 } 407 408 // when lazy load, size = 0, use it.k which is counted after it.Next() to check valid idx 409 if idx > it.k { 410 return errNode(meta.ErrInvalidParam, fmt.Sprintf("index '%d' is out of range", idx), nil) 411 } 412 413 s, e = it.Next(UseNativeSkipForGet) 414 v = self.slice(s, e, self.et) 415 return v 416 } 417 418 // Get string key of a MAP node 419 func (self Node) GetByStr(key string) (v Node) { 420 if err := self.should("Get", proto.MAP); err != "" { 421 return errNode(meta.ErrUnsupportedType, err, nil) 422 } 423 424 if self.kt != proto.STRING { 425 return errNode(meta.ErrUnsupportedType, "key type is not string", nil) 426 } 427 428 it := self.iterPairs() 429 if it.Err != nil { 430 return errNode(meta.ErrRead, "", it.Err) 431 } 432 433 for it.HasNext() { 434 _, s, ss, e := it.NextStr(UseNativeSkipForGet) 435 if it.Err != nil { 436 v = errNode(meta.ErrRead, "", it.Err) 437 goto ret 438 } 439 440 if s == key { 441 v = self.slice(ss, e, self.et) 442 goto ret 443 } 444 } 445 v = errNode(meta.ErrNotFound, fmt.Sprintf("key '%s' is not found in this value", key), errNotFound) 446 ret: 447 return 448 } 449 450 // Get int key of a MAP node 451 func (self Node) GetByInt(key int) (v Node) { 452 if err := self.should("Get", proto.MAP); err != "" { 453 return errNode(meta.ErrUnsupportedType, err, nil) 454 } 455 456 if !self.kt.IsInt() { 457 return errNode(meta.ErrUnsupportedType, "key type is not int", nil) 458 } 459 460 it := self.iterPairs() 461 if it.Err != nil { 462 return errNode(meta.ErrRead, "", it.Err) 463 } 464 465 for it.HasNext() { 466 _, i, ss, e := it.NextInt(UseNativeSkipForGet) 467 if it.Err != nil { 468 v = errNode(meta.ErrRead, "", it.Err) 469 goto ret 470 } 471 if i == key { 472 v = self.slice(ss, e, self.et) 473 goto ret 474 } 475 } 476 v = errNode(meta.ErrNotFound, fmt.Sprintf("key '%d' is not found in this value", key), nil) 477 ret: 478 return 479 } 480 481 func (self Node) Field(id proto.FieldNumber, rootLayer bool, msgDesc *proto.MessageDescriptor) (v Node, f *proto.FieldDescriptor) { 482 if err := self.should("Field", proto.MESSAGE); err != "" { 483 return errNode(meta.ErrUnsupportedType, err, nil), nil 484 } 485 486 fd := msgDesc.ByNumber(id) 487 488 if fd == nil { 489 return errNode(meta.ErrUnknownField, fmt.Sprintf("field '%d' is not defined in IDL", id), nil), nil 490 } 491 492 it := self.iterFields() 493 494 if it.Err != nil { 495 return errNode(meta.ErrRead, "", it.Err), nil 496 } 497 498 if !rootLayer { 499 if _, err := it.p.ReadLength(); err != nil { 500 return errNode(meta.ErrRead, "", err), nil 501 } 502 503 if it.Err != nil { 504 return errNode(meta.ErrRead, "", it.Err), nil 505 } 506 } 507 508 for it.HasNext() { 509 i, wt, s, e, tagPos := it.Next(UseNativeSkipForGet) 510 if i == fd.Number() { 511 typDesc := fd.Type() 512 if typDesc.IsMap() || typDesc.IsList() { 513 it.p.Read = tagPos 514 if _, err := it.p.SkipAllElements(i, typDesc.IsPacked()); err != nil { 515 return errNode(meta.ErrRead, "SkipAllElements in LIST/MAP failed", err), nil 516 } 517 s = tagPos 518 e = it.p.Read 519 520 v = self.sliceNodeWithDesc(s, e, typDesc) 521 goto ret 522 } 523 524 t := proto.Kind2Wire[fd.Kind()] 525 if wt != t { 526 v = errNode(meta.ErrDismatchType, fmt.Sprintf("field '%s' expects type %s, buf got type %s", fd.Name(), t, wt), nil) 527 goto ret 528 } 529 v = self.sliceNodeWithDesc(s, e, typDesc) 530 goto ret 531 } else if it.Err != nil { 532 v = errNode(meta.ErrRead, "", it.Err) 533 goto ret 534 } 535 } 536 537 v = errNode(meta.ErrNotFound, fmt.Sprintf("field '%d' is not found in this value", id), errNotFound) 538 ret: 539 return v, fd 540 } 541 542 func (self Node) Fields(ids []PathNode, rootLayer bool, msgDesc *proto.MessageDescriptor, opts *Options) error { 543 if err := self.should("Fields", proto.MESSAGE); err != "" { 544 return errNode(meta.ErrUnsupportedType, err, nil) 545 } 546 547 if len(ids) == 0 { 548 return nil 549 } 550 551 if opts.ClearDirtyValues { 552 for i := range ids { 553 ids[i].Node = Node{} 554 } 555 } 556 557 it := self.iterFields() 558 if it.Err != nil { 559 return errNode(meta.ErrRead, "", it.Err) 560 } 561 562 563 564 if !rootLayer { 565 if _, err := it.p.ReadLength(); err != nil { 566 return errNode(meta.ErrRead, "", err) 567 } 568 569 if it.Err != nil { 570 return errNode(meta.ErrRead, "", it.Err) 571 } 572 } 573 574 need := len(ids) 575 for count := 0; it.HasNext() && count < need; { 576 var p *PathNode 577 i, _, s, e, tagPos := it.Next(UseNativeSkipForGet) 578 if it.Err != nil { 579 return errNode(meta.ErrRead, "", it.Err) 580 } 581 f := msgDesc.ByNumber(i) 582 typDesc := f.Type() 583 if typDesc.IsMap() || typDesc.IsList() { 584 it.p.Read = tagPos 585 if _, err := it.p.SkipAllElements(i, typDesc.IsPacked()); err != nil { 586 return errNode(meta.ErrRead, "SkipAllElements in LIST/MAP failed", err) 587 } 588 s = tagPos 589 e = it.p.Read 590 } 591 592 v := self.sliceNodeWithDesc(s, e, typDesc) 593 594 //TODO: use bitmap to avoid repeatedly scan 595 for j, id := range ids { 596 if id.Path.t == PathFieldId && id.Path.id() == i { 597 p = &ids[j] 598 count += 1 599 break 600 } 601 } 602 603 if p != nil { 604 p.Node = v 605 } 606 } 607 608 return nil 609 } 610 611 func (self Node) Indexes(ins []PathNode, opts *Options) error { 612 if err := self.should("Indexes", proto.LIST); err != "" { 613 return errNode(meta.ErrUnsupportedType, err, nil) 614 } 615 616 if len(ins) == 0 { 617 return nil 618 } 619 620 if opts.ClearDirtyValues { 621 for i := range ins { 622 ins[i].Node = Node{} 623 } 624 } 625 626 it := self.iterElems() 627 if it.Err != nil { 628 return errNode(meta.ErrRead, "", it.Err) 629 } 630 631 need := len(ins) 632 IsPacked := it.IsPacked() 633 634 // read packed list tag and bytelen 635 if IsPacked { 636 if _, _, _, err := it.p.ConsumeTag(); err != nil { 637 return errNode(meta.ErrRead, "", err) 638 } 639 if _, err := it.p.ReadLength(); err != nil { 640 return errNode(meta.ErrRead, "", err) 641 } 642 } 643 644 for count, i := 0, 0; it.HasNext() && count < need; i++ { 645 s, e := it.Next(UseNativeSkipForGet) 646 if it.Err != nil { 647 return errNode(meta.ErrRead, "", it.Err) 648 } 649 650 // check if the index is in the pathes 651 var p *PathNode 652 for j, id := range ins { 653 if id.Path.t != PathIndex { 654 continue 655 } 656 k := id.Path.int() 657 if k >= it.size { 658 continue 659 } 660 if k == i { 661 p = &ins[j] 662 count += 1 663 break 664 } 665 } 666 // PathNode is found 667 if p != nil { 668 p.Node = self.slice(s, e, self.et) 669 } 670 } 671 return nil 672 } 673 674 func (self Node) Gets(keys []PathNode, opts *Options) error { 675 if err := self.should("Gets", proto.MAP); err != "" { 676 return errNode(meta.ErrUnsupportedType, err, nil) 677 } 678 679 if len(keys) == 0 { 680 return nil 681 } 682 683 if opts.ClearDirtyValues { 684 for i := range keys { 685 keys[i].Node = Node{} 686 } 687 } 688 689 et := self.et 690 it := self.iterPairs() 691 if it.Err != nil { 692 return errNode(meta.ErrRead, "", it.Err) 693 } 694 695 need := len(keys) 696 for count := 0; it.HasNext() && count < need; { 697 for j, id := range keys { 698 if id.Path.Type() == PathStrKey { 699 exp := id.Path.str() 700 _, key, s, e := it.NextStr(UseNativeSkipForGet) 701 if it.Err != nil { 702 return errNode(meta.ErrRead, "", it.Err) 703 } 704 if key == exp { 705 keys[j].Node = self.slice(s, e, et) 706 count += 1 707 break 708 } 709 } else if id.Path.Type() == PathIntKey { 710 exp := id.Path.int() 711 _, key, s, e := it.NextInt(UseNativeSkipForGet) 712 if it.Err != nil { 713 return errNode(meta.ErrRead, "", it.Err) 714 } 715 if key == exp { 716 keys[j].Node = self.slice(s, e, et) 717 count += 1 718 break 719 } 720 } 721 } 722 } 723 return nil 724 }