path.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. package decoder
  2. import (
  3. "fmt"
  4. "reflect"
  5. "strconv"
  6. "github.com/goccy/go-json/internal/errors"
  7. "github.com/goccy/go-json/internal/runtime"
  8. )
  9. type PathString string
  10. func (s PathString) Build() (*Path, error) {
  11. builder := new(PathBuilder)
  12. return builder.Build([]rune(s))
  13. }
  14. type PathBuilder struct {
  15. root PathNode
  16. node PathNode
  17. singleQuotePathSelector bool
  18. doubleQuotePathSelector bool
  19. }
  20. func (b *PathBuilder) Build(buf []rune) (*Path, error) {
  21. node, err := b.build(buf)
  22. if err != nil {
  23. return nil, err
  24. }
  25. return &Path{
  26. node: node,
  27. RootSelectorOnly: node == nil,
  28. SingleQuotePathSelector: b.singleQuotePathSelector,
  29. DoubleQuotePathSelector: b.doubleQuotePathSelector,
  30. }, nil
  31. }
  32. func (b *PathBuilder) build(buf []rune) (PathNode, error) {
  33. if len(buf) == 0 {
  34. return nil, errors.ErrEmptyPath()
  35. }
  36. if buf[0] != '$' {
  37. return nil, errors.ErrInvalidPath("JSON Path must start with a $ character")
  38. }
  39. if len(buf) == 1 {
  40. return nil, nil
  41. }
  42. buf = buf[1:]
  43. offset, err := b.buildNext(buf)
  44. if err != nil {
  45. return nil, err
  46. }
  47. if len(buf) > offset {
  48. return nil, errors.ErrInvalidPath("remain invalid path %q", buf[offset:])
  49. }
  50. return b.root, nil
  51. }
  52. func (b *PathBuilder) buildNextCharIfExists(buf []rune, cursor int) (int, error) {
  53. if len(buf) > cursor {
  54. offset, err := b.buildNext(buf[cursor:])
  55. if err != nil {
  56. return 0, err
  57. }
  58. return cursor + 1 + offset, nil
  59. }
  60. return cursor, nil
  61. }
  62. func (b *PathBuilder) buildNext(buf []rune) (int, error) {
  63. switch buf[0] {
  64. case '.':
  65. if len(buf) == 1 {
  66. return 0, errors.ErrInvalidPath("JSON Path ends with dot character")
  67. }
  68. offset, err := b.buildSelector(buf[1:])
  69. if err != nil {
  70. return 0, err
  71. }
  72. return offset + 1, nil
  73. case '[':
  74. if len(buf) == 1 {
  75. return 0, errors.ErrInvalidPath("JSON Path ends with left bracket character")
  76. }
  77. offset, err := b.buildIndex(buf[1:])
  78. if err != nil {
  79. return 0, err
  80. }
  81. return offset + 1, nil
  82. default:
  83. return 0, errors.ErrInvalidPath("expect dot or left bracket character. but found %c character", buf[0])
  84. }
  85. }
  86. func (b *PathBuilder) buildSelector(buf []rune) (int, error) {
  87. switch buf[0] {
  88. case '.':
  89. if len(buf) == 1 {
  90. return 0, errors.ErrInvalidPath("JSON Path ends with double dot character")
  91. }
  92. offset, err := b.buildPathRecursive(buf[1:])
  93. if err != nil {
  94. return 0, err
  95. }
  96. return 1 + offset, nil
  97. case '[', ']', '$', '*':
  98. return 0, errors.ErrInvalidPath("found invalid path character %c after dot", buf[0])
  99. }
  100. for cursor := 0; cursor < len(buf); cursor++ {
  101. switch buf[cursor] {
  102. case '$', '*', ']':
  103. return 0, errors.ErrInvalidPath("found %c character in field selector context", buf[cursor])
  104. case '.':
  105. if cursor+1 >= len(buf) {
  106. return 0, errors.ErrInvalidPath("JSON Path ends with dot character")
  107. }
  108. selector := buf[:cursor]
  109. b.addSelectorNode(string(selector))
  110. offset, err := b.buildSelector(buf[cursor+1:])
  111. if err != nil {
  112. return 0, err
  113. }
  114. return cursor + 1 + offset, nil
  115. case '[':
  116. if cursor+1 >= len(buf) {
  117. return 0, errors.ErrInvalidPath("JSON Path ends with left bracket character")
  118. }
  119. selector := buf[:cursor]
  120. b.addSelectorNode(string(selector))
  121. offset, err := b.buildIndex(buf[cursor+1:])
  122. if err != nil {
  123. return 0, err
  124. }
  125. return cursor + 1 + offset, nil
  126. case '"':
  127. if cursor+1 >= len(buf) {
  128. return 0, errors.ErrInvalidPath("JSON Path ends with double quote character")
  129. }
  130. offset, err := b.buildQuoteSelector(buf[cursor+1:], DoubleQuotePathSelector)
  131. if err != nil {
  132. return 0, err
  133. }
  134. return cursor + 1 + offset, nil
  135. }
  136. }
  137. b.addSelectorNode(string(buf))
  138. return len(buf), nil
  139. }
  140. func (b *PathBuilder) buildQuoteSelector(buf []rune, sel QuotePathSelector) (int, error) {
  141. switch buf[0] {
  142. case '[', ']', '$', '.', '*', '\'', '"':
  143. return 0, errors.ErrInvalidPath("found invalid path character %c after quote", buf[0])
  144. }
  145. for cursor := 0; cursor < len(buf); cursor++ {
  146. switch buf[cursor] {
  147. case '\'':
  148. if sel != SingleQuotePathSelector {
  149. return 0, errors.ErrInvalidPath("found double quote character in field selector with single quote context")
  150. }
  151. if len(buf) <= cursor+1 {
  152. return 0, errors.ErrInvalidPath("JSON Path ends with single quote character in field selector context")
  153. }
  154. if buf[cursor+1] != ']' {
  155. return 0, errors.ErrInvalidPath("expect right bracket for field selector with single quote but found %c", buf[cursor+1])
  156. }
  157. selector := buf[:cursor]
  158. b.addSelectorNode(string(selector))
  159. b.singleQuotePathSelector = true
  160. return b.buildNextCharIfExists(buf, cursor+2)
  161. case '"':
  162. if sel != DoubleQuotePathSelector {
  163. return 0, errors.ErrInvalidPath("found single quote character in field selector with double quote context")
  164. }
  165. selector := buf[:cursor]
  166. b.addSelectorNode(string(selector))
  167. b.doubleQuotePathSelector = true
  168. return b.buildNextCharIfExists(buf, cursor+1)
  169. }
  170. }
  171. return 0, errors.ErrInvalidPath("couldn't find quote character in selector quote path context")
  172. }
  173. func (b *PathBuilder) buildPathRecursive(buf []rune) (int, error) {
  174. switch buf[0] {
  175. case '.', '[', ']', '$', '*':
  176. return 0, errors.ErrInvalidPath("found invalid path character %c after double dot", buf[0])
  177. }
  178. for cursor := 0; cursor < len(buf); cursor++ {
  179. switch buf[cursor] {
  180. case '$', '*', ']':
  181. return 0, errors.ErrInvalidPath("found %c character in field selector context", buf[cursor])
  182. case '.':
  183. if cursor+1 >= len(buf) {
  184. return 0, errors.ErrInvalidPath("JSON Path ends with dot character")
  185. }
  186. selector := buf[:cursor]
  187. b.addRecursiveNode(string(selector))
  188. offset, err := b.buildSelector(buf[cursor+1:])
  189. if err != nil {
  190. return 0, err
  191. }
  192. return cursor + 1 + offset, nil
  193. case '[':
  194. if cursor+1 >= len(buf) {
  195. return 0, errors.ErrInvalidPath("JSON Path ends with left bracket character")
  196. }
  197. selector := buf[:cursor]
  198. b.addRecursiveNode(string(selector))
  199. offset, err := b.buildIndex(buf[cursor+1:])
  200. if err != nil {
  201. return 0, err
  202. }
  203. return cursor + 1 + offset, nil
  204. }
  205. }
  206. b.addRecursiveNode(string(buf))
  207. return len(buf), nil
  208. }
  209. func (b *PathBuilder) buildIndex(buf []rune) (int, error) {
  210. switch buf[0] {
  211. case '.', '[', ']', '$':
  212. return 0, errors.ErrInvalidPath("found invalid path character %c after left bracket", buf[0])
  213. case '\'':
  214. if len(buf) == 1 {
  215. return 0, errors.ErrInvalidPath("JSON Path ends with single quote character")
  216. }
  217. offset, err := b.buildQuoteSelector(buf[1:], SingleQuotePathSelector)
  218. if err != nil {
  219. return 0, err
  220. }
  221. return 1 + offset, nil
  222. case '*':
  223. if len(buf) == 1 {
  224. return 0, errors.ErrInvalidPath("JSON Path ends with star character")
  225. }
  226. if buf[1] != ']' {
  227. return 0, errors.ErrInvalidPath("expect right bracket character for index all path but found %c character", buf[1])
  228. }
  229. b.addIndexAllNode()
  230. offset := len("*]")
  231. if len(buf) > 2 {
  232. buildOffset, err := b.buildNext(buf[2:])
  233. if err != nil {
  234. return 0, err
  235. }
  236. return offset + buildOffset, nil
  237. }
  238. return offset, nil
  239. }
  240. for cursor := 0; cursor < len(buf); cursor++ {
  241. switch buf[cursor] {
  242. case ']':
  243. index, err := strconv.ParseInt(string(buf[:cursor]), 10, 64)
  244. if err != nil {
  245. return 0, errors.ErrInvalidPath("%q is unexpected index path", buf[:cursor])
  246. }
  247. b.addIndexNode(int(index))
  248. return b.buildNextCharIfExists(buf, cursor+1)
  249. }
  250. }
  251. return 0, errors.ErrInvalidPath("couldn't find right bracket character in index path context")
  252. }
  253. func (b *PathBuilder) addIndexAllNode() {
  254. node := newPathIndexAllNode()
  255. if b.root == nil {
  256. b.root = node
  257. b.node = node
  258. } else {
  259. b.node = b.node.chain(node)
  260. }
  261. }
  262. func (b *PathBuilder) addRecursiveNode(selector string) {
  263. node := newPathRecursiveNode(selector)
  264. if b.root == nil {
  265. b.root = node
  266. b.node = node
  267. } else {
  268. b.node = b.node.chain(node)
  269. }
  270. }
  271. func (b *PathBuilder) addSelectorNode(name string) {
  272. node := newPathSelectorNode(name)
  273. if b.root == nil {
  274. b.root = node
  275. b.node = node
  276. } else {
  277. b.node = b.node.chain(node)
  278. }
  279. }
  280. func (b *PathBuilder) addIndexNode(idx int) {
  281. node := newPathIndexNode(idx)
  282. if b.root == nil {
  283. b.root = node
  284. b.node = node
  285. } else {
  286. b.node = b.node.chain(node)
  287. }
  288. }
  289. type QuotePathSelector int
  290. const (
  291. SingleQuotePathSelector QuotePathSelector = 1
  292. DoubleQuotePathSelector QuotePathSelector = 2
  293. )
  294. type Path struct {
  295. node PathNode
  296. RootSelectorOnly bool
  297. SingleQuotePathSelector bool
  298. DoubleQuotePathSelector bool
  299. }
  300. func (p *Path) Field(sel string) (PathNode, bool, error) {
  301. if p.node == nil {
  302. return nil, false, nil
  303. }
  304. return p.node.Field(sel)
  305. }
  306. func (p *Path) Get(src, dst reflect.Value) error {
  307. if p.node == nil {
  308. return nil
  309. }
  310. return p.node.Get(src, dst)
  311. }
  312. func (p *Path) String() string {
  313. if p.node == nil {
  314. return "$"
  315. }
  316. return p.node.String()
  317. }
  318. type PathNode interface {
  319. fmt.Stringer
  320. Index(idx int) (PathNode, bool, error)
  321. Field(fieldName string) (PathNode, bool, error)
  322. Get(src, dst reflect.Value) error
  323. chain(PathNode) PathNode
  324. target() bool
  325. single() bool
  326. }
  327. type BasePathNode struct {
  328. child PathNode
  329. }
  330. func (n *BasePathNode) chain(node PathNode) PathNode {
  331. n.child = node
  332. return node
  333. }
  334. func (n *BasePathNode) target() bool {
  335. return n.child == nil
  336. }
  337. func (n *BasePathNode) single() bool {
  338. return true
  339. }
  340. type PathSelectorNode struct {
  341. *BasePathNode
  342. selector string
  343. }
  344. func newPathSelectorNode(selector string) *PathSelectorNode {
  345. return &PathSelectorNode{
  346. BasePathNode: &BasePathNode{},
  347. selector: selector,
  348. }
  349. }
  350. func (n *PathSelectorNode) Index(idx int) (PathNode, bool, error) {
  351. return nil, false, &errors.PathError{}
  352. }
  353. func (n *PathSelectorNode) Field(fieldName string) (PathNode, bool, error) {
  354. if n.selector == fieldName {
  355. return n.child, true, nil
  356. }
  357. return nil, false, nil
  358. }
  359. func (n *PathSelectorNode) Get(src, dst reflect.Value) error {
  360. switch src.Type().Kind() {
  361. case reflect.Map:
  362. iter := src.MapRange()
  363. for iter.Next() {
  364. key, ok := iter.Key().Interface().(string)
  365. if !ok {
  366. return fmt.Errorf("invalid map key type %T", src.Type().Key())
  367. }
  368. child, found, err := n.Field(key)
  369. if err != nil {
  370. return err
  371. }
  372. if found {
  373. if child != nil {
  374. return child.Get(iter.Value(), dst)
  375. }
  376. return AssignValue(iter.Value(), dst)
  377. }
  378. }
  379. case reflect.Struct:
  380. typ := src.Type()
  381. for i := 0; i < typ.Len(); i++ {
  382. tag := runtime.StructTagFromField(typ.Field(i))
  383. child, found, err := n.Field(tag.Key)
  384. if err != nil {
  385. return err
  386. }
  387. if found {
  388. if child != nil {
  389. return child.Get(src.Field(i), dst)
  390. }
  391. return AssignValue(src.Field(i), dst)
  392. }
  393. }
  394. case reflect.Ptr:
  395. return n.Get(src.Elem(), dst)
  396. case reflect.Interface:
  397. return n.Get(reflect.ValueOf(src.Interface()), dst)
  398. case reflect.Float64, reflect.String, reflect.Bool:
  399. return AssignValue(src, dst)
  400. }
  401. return fmt.Errorf("failed to get %s value from %s", n.selector, src.Type())
  402. }
  403. func (n *PathSelectorNode) String() string {
  404. s := fmt.Sprintf(".%s", n.selector)
  405. if n.child != nil {
  406. s += n.child.String()
  407. }
  408. return s
  409. }
  410. type PathIndexNode struct {
  411. *BasePathNode
  412. selector int
  413. }
  414. func newPathIndexNode(selector int) *PathIndexNode {
  415. return &PathIndexNode{
  416. BasePathNode: &BasePathNode{},
  417. selector: selector,
  418. }
  419. }
  420. func (n *PathIndexNode) Index(idx int) (PathNode, bool, error) {
  421. if n.selector == idx {
  422. return n.child, true, nil
  423. }
  424. return nil, false, nil
  425. }
  426. func (n *PathIndexNode) Field(fieldName string) (PathNode, bool, error) {
  427. return nil, false, &errors.PathError{}
  428. }
  429. func (n *PathIndexNode) Get(src, dst reflect.Value) error {
  430. switch src.Type().Kind() {
  431. case reflect.Array, reflect.Slice:
  432. if src.Len() > n.selector {
  433. if n.child != nil {
  434. return n.child.Get(src.Index(n.selector), dst)
  435. }
  436. return AssignValue(src.Index(n.selector), dst)
  437. }
  438. case reflect.Ptr:
  439. return n.Get(src.Elem(), dst)
  440. case reflect.Interface:
  441. return n.Get(reflect.ValueOf(src.Interface()), dst)
  442. }
  443. return fmt.Errorf("failed to get [%d] value from %s", n.selector, src.Type())
  444. }
  445. func (n *PathIndexNode) String() string {
  446. s := fmt.Sprintf("[%d]", n.selector)
  447. if n.child != nil {
  448. s += n.child.String()
  449. }
  450. return s
  451. }
  452. type PathIndexAllNode struct {
  453. *BasePathNode
  454. }
  455. func newPathIndexAllNode() *PathIndexAllNode {
  456. return &PathIndexAllNode{
  457. BasePathNode: &BasePathNode{},
  458. }
  459. }
  460. func (n *PathIndexAllNode) Index(idx int) (PathNode, bool, error) {
  461. return n.child, true, nil
  462. }
  463. func (n *PathIndexAllNode) Field(fieldName string) (PathNode, bool, error) {
  464. return nil, false, &errors.PathError{}
  465. }
  466. func (n *PathIndexAllNode) Get(src, dst reflect.Value) error {
  467. switch src.Type().Kind() {
  468. case reflect.Array, reflect.Slice:
  469. var arr []interface{}
  470. for i := 0; i < src.Len(); i++ {
  471. var v interface{}
  472. rv := reflect.ValueOf(&v)
  473. if n.child != nil {
  474. if err := n.child.Get(src.Index(i), rv); err != nil {
  475. return err
  476. }
  477. } else {
  478. if err := AssignValue(src.Index(i), rv); err != nil {
  479. return err
  480. }
  481. }
  482. arr = append(arr, v)
  483. }
  484. if err := AssignValue(reflect.ValueOf(arr), dst); err != nil {
  485. return err
  486. }
  487. return nil
  488. case reflect.Ptr:
  489. return n.Get(src.Elem(), dst)
  490. case reflect.Interface:
  491. return n.Get(reflect.ValueOf(src.Interface()), dst)
  492. }
  493. return fmt.Errorf("failed to get all value from %s", src.Type())
  494. }
  495. func (n *PathIndexAllNode) String() string {
  496. s := "[*]"
  497. if n.child != nil {
  498. s += n.child.String()
  499. }
  500. return s
  501. }
  502. type PathRecursiveNode struct {
  503. *BasePathNode
  504. selector string
  505. }
  506. func newPathRecursiveNode(selector string) *PathRecursiveNode {
  507. node := newPathSelectorNode(selector)
  508. return &PathRecursiveNode{
  509. BasePathNode: &BasePathNode{
  510. child: node,
  511. },
  512. selector: selector,
  513. }
  514. }
  515. func (n *PathRecursiveNode) Field(fieldName string) (PathNode, bool, error) {
  516. if n.selector == fieldName {
  517. return n.child, true, nil
  518. }
  519. return nil, false, nil
  520. }
  521. func (n *PathRecursiveNode) Index(_ int) (PathNode, bool, error) {
  522. return n, true, nil
  523. }
  524. func valueToSliceValue(v interface{}) []interface{} {
  525. rv := reflect.ValueOf(v)
  526. ret := []interface{}{}
  527. if rv.Type().Kind() == reflect.Slice || rv.Type().Kind() == reflect.Array {
  528. for i := 0; i < rv.Len(); i++ {
  529. ret = append(ret, rv.Index(i).Interface())
  530. }
  531. return ret
  532. }
  533. return []interface{}{v}
  534. }
  535. func (n *PathRecursiveNode) Get(src, dst reflect.Value) error {
  536. if n.child == nil {
  537. return fmt.Errorf("failed to get by recursive path ..%s", n.selector)
  538. }
  539. var arr []interface{}
  540. switch src.Type().Kind() {
  541. case reflect.Map:
  542. iter := src.MapRange()
  543. for iter.Next() {
  544. key, ok := iter.Key().Interface().(string)
  545. if !ok {
  546. return fmt.Errorf("invalid map key type %T", src.Type().Key())
  547. }
  548. child, found, err := n.Field(key)
  549. if err != nil {
  550. return err
  551. }
  552. if found {
  553. var v interface{}
  554. rv := reflect.ValueOf(&v)
  555. _ = child.Get(iter.Value(), rv)
  556. arr = append(arr, valueToSliceValue(v)...)
  557. } else {
  558. var v interface{}
  559. rv := reflect.ValueOf(&v)
  560. _ = n.Get(iter.Value(), rv)
  561. if v != nil {
  562. arr = append(arr, valueToSliceValue(v)...)
  563. }
  564. }
  565. }
  566. _ = AssignValue(reflect.ValueOf(arr), dst)
  567. return nil
  568. case reflect.Struct:
  569. typ := src.Type()
  570. for i := 0; i < typ.Len(); i++ {
  571. tag := runtime.StructTagFromField(typ.Field(i))
  572. child, found, err := n.Field(tag.Key)
  573. if err != nil {
  574. return err
  575. }
  576. if found {
  577. var v interface{}
  578. rv := reflect.ValueOf(&v)
  579. _ = child.Get(src.Field(i), rv)
  580. arr = append(arr, valueToSliceValue(v)...)
  581. } else {
  582. var v interface{}
  583. rv := reflect.ValueOf(&v)
  584. _ = n.Get(src.Field(i), rv)
  585. if v != nil {
  586. arr = append(arr, valueToSliceValue(v)...)
  587. }
  588. }
  589. }
  590. _ = AssignValue(reflect.ValueOf(arr), dst)
  591. return nil
  592. case reflect.Array, reflect.Slice:
  593. for i := 0; i < src.Len(); i++ {
  594. var v interface{}
  595. rv := reflect.ValueOf(&v)
  596. _ = n.Get(src.Index(i), rv)
  597. if v != nil {
  598. arr = append(arr, valueToSliceValue(v)...)
  599. }
  600. }
  601. _ = AssignValue(reflect.ValueOf(arr), dst)
  602. return nil
  603. case reflect.Ptr:
  604. return n.Get(src.Elem(), dst)
  605. case reflect.Interface:
  606. return n.Get(reflect.ValueOf(src.Interface()), dst)
  607. }
  608. return fmt.Errorf("failed to get %s value from %s", n.selector, src.Type())
  609. }
  610. func (n *PathRecursiveNode) String() string {
  611. s := fmt.Sprintf("..%s", n.selector)
  612. if n.child != nil {
  613. s += n.child.String()
  614. }
  615. return s
  616. }