interpreter.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. package jmespath
  2. import (
  3. "errors"
  4. "reflect"
  5. "unicode"
  6. "unicode/utf8"
  7. )
  8. /* This is a tree based interpreter. It walks the AST and directly
  9. interprets the AST to search through a JSON document.
  10. */
  11. type treeInterpreter struct {
  12. fCall *functionCaller
  13. }
  14. func newInterpreter() *treeInterpreter {
  15. interpreter := treeInterpreter{}
  16. interpreter.fCall = newFunctionCaller()
  17. return &interpreter
  18. }
  19. type expRef struct {
  20. ref ASTNode
  21. }
  22. // Execute takes an ASTNode and input data and interprets the AST directly.
  23. // It will produce the result of applying the JMESPath expression associated
  24. // with the ASTNode to the input data "value".
  25. func (intr *treeInterpreter) Execute(node ASTNode, value interface{}) (interface{}, error) {
  26. switch node.nodeType {
  27. case ASTComparator:
  28. left, err := intr.Execute(node.children[0], value)
  29. if err != nil {
  30. return nil, err
  31. }
  32. right, err := intr.Execute(node.children[1], value)
  33. if err != nil {
  34. return nil, err
  35. }
  36. switch node.value {
  37. case tEQ:
  38. return objsEqual(left, right), nil
  39. case tNE:
  40. return !objsEqual(left, right), nil
  41. }
  42. leftNum, ok := left.(float64)
  43. if !ok {
  44. return nil, nil
  45. }
  46. rightNum, ok := right.(float64)
  47. if !ok {
  48. return nil, nil
  49. }
  50. switch node.value {
  51. case tGT:
  52. return leftNum > rightNum, nil
  53. case tGTE:
  54. return leftNum >= rightNum, nil
  55. case tLT:
  56. return leftNum < rightNum, nil
  57. case tLTE:
  58. return leftNum <= rightNum, nil
  59. }
  60. case ASTExpRef:
  61. return expRef{ref: node.children[0]}, nil
  62. case ASTFunctionExpression:
  63. resolvedArgs := []interface{}{}
  64. for _, arg := range node.children {
  65. current, err := intr.Execute(arg, value)
  66. if err != nil {
  67. return nil, err
  68. }
  69. resolvedArgs = append(resolvedArgs, current)
  70. }
  71. return intr.fCall.CallFunction(node.value.(string), resolvedArgs, intr)
  72. case ASTField:
  73. if m, ok := value.(map[string]interface{}); ok {
  74. key := node.value.(string)
  75. return m[key], nil
  76. }
  77. return intr.fieldFromStruct(node.value.(string), value)
  78. case ASTFilterProjection:
  79. left, err := intr.Execute(node.children[0], value)
  80. if err != nil {
  81. return nil, nil
  82. }
  83. sliceType, ok := left.([]interface{})
  84. if !ok {
  85. if isSliceType(left) {
  86. return intr.filterProjectionWithReflection(node, left)
  87. }
  88. return nil, nil
  89. }
  90. compareNode := node.children[2]
  91. collected := []interface{}{}
  92. for _, element := range sliceType {
  93. result, err := intr.Execute(compareNode, element)
  94. if err != nil {
  95. return nil, err
  96. }
  97. if !isFalse(result) {
  98. current, err := intr.Execute(node.children[1], element)
  99. if err != nil {
  100. return nil, err
  101. }
  102. if current != nil {
  103. collected = append(collected, current)
  104. }
  105. }
  106. }
  107. return collected, nil
  108. case ASTFlatten:
  109. left, err := intr.Execute(node.children[0], value)
  110. if err != nil {
  111. return nil, nil
  112. }
  113. sliceType, ok := left.([]interface{})
  114. if !ok {
  115. // If we can't type convert to []interface{}, there's
  116. // a chance this could still work via reflection if we're
  117. // dealing with user provided types.
  118. if isSliceType(left) {
  119. return intr.flattenWithReflection(left)
  120. }
  121. return nil, nil
  122. }
  123. flattened := []interface{}{}
  124. for _, element := range sliceType {
  125. if elementSlice, ok := element.([]interface{}); ok {
  126. flattened = append(flattened, elementSlice...)
  127. } else if isSliceType(element) {
  128. reflectFlat := []interface{}{}
  129. v := reflect.ValueOf(element)
  130. for i := 0; i < v.Len(); i++ {
  131. reflectFlat = append(reflectFlat, v.Index(i).Interface())
  132. }
  133. flattened = append(flattened, reflectFlat...)
  134. } else {
  135. flattened = append(flattened, element)
  136. }
  137. }
  138. return flattened, nil
  139. case ASTIdentity, ASTCurrentNode:
  140. return value, nil
  141. case ASTIndex:
  142. if sliceType, ok := value.([]interface{}); ok {
  143. index := node.value.(int)
  144. if index < 0 {
  145. index += len(sliceType)
  146. }
  147. if index < len(sliceType) && index >= 0 {
  148. return sliceType[index], nil
  149. }
  150. return nil, nil
  151. }
  152. // Otherwise try via reflection.
  153. rv := reflect.ValueOf(value)
  154. if rv.Kind() == reflect.Slice {
  155. index := node.value.(int)
  156. if index < 0 {
  157. index += rv.Len()
  158. }
  159. if index < rv.Len() && index >= 0 {
  160. v := rv.Index(index)
  161. return v.Interface(), nil
  162. }
  163. }
  164. return nil, nil
  165. case ASTKeyValPair:
  166. return intr.Execute(node.children[0], value)
  167. case ASTLiteral:
  168. return node.value, nil
  169. case ASTMultiSelectHash:
  170. if value == nil {
  171. return nil, nil
  172. }
  173. collected := make(map[string]interface{})
  174. for _, child := range node.children {
  175. current, err := intr.Execute(child, value)
  176. if err != nil {
  177. return nil, err
  178. }
  179. key := child.value.(string)
  180. collected[key] = current
  181. }
  182. return collected, nil
  183. case ASTMultiSelectList:
  184. if value == nil {
  185. return nil, nil
  186. }
  187. collected := []interface{}{}
  188. for _, child := range node.children {
  189. current, err := intr.Execute(child, value)
  190. if err != nil {
  191. return nil, err
  192. }
  193. collected = append(collected, current)
  194. }
  195. return collected, nil
  196. case ASTOrExpression:
  197. matched, err := intr.Execute(node.children[0], value)
  198. if err != nil {
  199. return nil, err
  200. }
  201. if isFalse(matched) {
  202. matched, err = intr.Execute(node.children[1], value)
  203. if err != nil {
  204. return nil, err
  205. }
  206. }
  207. return matched, nil
  208. case ASTAndExpression:
  209. matched, err := intr.Execute(node.children[0], value)
  210. if err != nil {
  211. return nil, err
  212. }
  213. if isFalse(matched) {
  214. return matched, nil
  215. }
  216. return intr.Execute(node.children[1], value)
  217. case ASTNotExpression:
  218. matched, err := intr.Execute(node.children[0], value)
  219. if err != nil {
  220. return nil, err
  221. }
  222. if isFalse(matched) {
  223. return true, nil
  224. }
  225. return false, nil
  226. case ASTPipe:
  227. result := value
  228. var err error
  229. for _, child := range node.children {
  230. result, err = intr.Execute(child, result)
  231. if err != nil {
  232. return nil, err
  233. }
  234. }
  235. return result, nil
  236. case ASTProjection:
  237. left, err := intr.Execute(node.children[0], value)
  238. if err != nil {
  239. return nil, err
  240. }
  241. sliceType, ok := left.([]interface{})
  242. if !ok {
  243. if isSliceType(left) {
  244. return intr.projectWithReflection(node, left)
  245. }
  246. return nil, nil
  247. }
  248. collected := []interface{}{}
  249. var current interface{}
  250. for _, element := range sliceType {
  251. current, err = intr.Execute(node.children[1], element)
  252. if err != nil {
  253. return nil, err
  254. }
  255. if current != nil {
  256. collected = append(collected, current)
  257. }
  258. }
  259. return collected, nil
  260. case ASTSubexpression, ASTIndexExpression:
  261. left, err := intr.Execute(node.children[0], value)
  262. if err != nil {
  263. return nil, err
  264. }
  265. return intr.Execute(node.children[1], left)
  266. case ASTSlice:
  267. sliceType, ok := value.([]interface{})
  268. if !ok {
  269. if isSliceType(value) {
  270. return intr.sliceWithReflection(node, value)
  271. }
  272. return nil, nil
  273. }
  274. parts := node.value.([]*int)
  275. sliceParams := make([]sliceParam, 3)
  276. for i, part := range parts {
  277. if part != nil {
  278. sliceParams[i].Specified = true
  279. sliceParams[i].N = *part
  280. }
  281. }
  282. return slice(sliceType, sliceParams)
  283. case ASTValueProjection:
  284. left, err := intr.Execute(node.children[0], value)
  285. if err != nil {
  286. return nil, nil
  287. }
  288. mapType, ok := left.(map[string]interface{})
  289. if !ok {
  290. return nil, nil
  291. }
  292. values := make([]interface{}, len(mapType))
  293. for _, value := range mapType {
  294. values = append(values, value)
  295. }
  296. collected := []interface{}{}
  297. for _, element := range values {
  298. current, err := intr.Execute(node.children[1], element)
  299. if err != nil {
  300. return nil, err
  301. }
  302. if current != nil {
  303. collected = append(collected, current)
  304. }
  305. }
  306. return collected, nil
  307. }
  308. return nil, errors.New("Unknown AST node: " + node.nodeType.String())
  309. }
  310. func (intr *treeInterpreter) fieldFromStruct(key string, value interface{}) (interface{}, error) {
  311. rv := reflect.ValueOf(value)
  312. first, n := utf8.DecodeRuneInString(key)
  313. fieldName := string(unicode.ToUpper(first)) + key[n:]
  314. if rv.Kind() == reflect.Struct {
  315. v := rv.FieldByName(fieldName)
  316. if !v.IsValid() {
  317. return nil, nil
  318. }
  319. return v.Interface(), nil
  320. } else if rv.Kind() == reflect.Ptr {
  321. // Handle multiple levels of indirection?
  322. if rv.IsNil() {
  323. return nil, nil
  324. }
  325. rv = rv.Elem()
  326. v := rv.FieldByName(fieldName)
  327. if !v.IsValid() {
  328. return nil, nil
  329. }
  330. return v.Interface(), nil
  331. }
  332. return nil, nil
  333. }
  334. func (intr *treeInterpreter) flattenWithReflection(value interface{}) (interface{}, error) {
  335. v := reflect.ValueOf(value)
  336. flattened := []interface{}{}
  337. for i := 0; i < v.Len(); i++ {
  338. element := v.Index(i).Interface()
  339. if reflect.TypeOf(element).Kind() == reflect.Slice {
  340. // Then insert the contents of the element
  341. // slice into the flattened slice,
  342. // i.e flattened = append(flattened, mySlice...)
  343. elementV := reflect.ValueOf(element)
  344. for j := 0; j < elementV.Len(); j++ {
  345. flattened = append(
  346. flattened, elementV.Index(j).Interface())
  347. }
  348. } else {
  349. flattened = append(flattened, element)
  350. }
  351. }
  352. return flattened, nil
  353. }
  354. func (intr *treeInterpreter) sliceWithReflection(node ASTNode, value interface{}) (interface{}, error) {
  355. v := reflect.ValueOf(value)
  356. parts := node.value.([]*int)
  357. sliceParams := make([]sliceParam, 3)
  358. for i, part := range parts {
  359. if part != nil {
  360. sliceParams[i].Specified = true
  361. sliceParams[i].N = *part
  362. }
  363. }
  364. final := []interface{}{}
  365. for i := 0; i < v.Len(); i++ {
  366. element := v.Index(i).Interface()
  367. final = append(final, element)
  368. }
  369. return slice(final, sliceParams)
  370. }
  371. func (intr *treeInterpreter) filterProjectionWithReflection(node ASTNode, value interface{}) (interface{}, error) {
  372. compareNode := node.children[2]
  373. collected := []interface{}{}
  374. v := reflect.ValueOf(value)
  375. for i := 0; i < v.Len(); i++ {
  376. element := v.Index(i).Interface()
  377. result, err := intr.Execute(compareNode, element)
  378. if err != nil {
  379. return nil, err
  380. }
  381. if !isFalse(result) {
  382. current, err := intr.Execute(node.children[1], element)
  383. if err != nil {
  384. return nil, err
  385. }
  386. if current != nil {
  387. collected = append(collected, current)
  388. }
  389. }
  390. }
  391. return collected, nil
  392. }
  393. func (intr *treeInterpreter) projectWithReflection(node ASTNode, value interface{}) (interface{}, error) {
  394. collected := []interface{}{}
  395. v := reflect.ValueOf(value)
  396. for i := 0; i < v.Len(); i++ {
  397. element := v.Index(i).Interface()
  398. result, err := intr.Execute(node.children[1], element)
  399. if err != nil {
  400. return nil, err
  401. }
  402. if result != nil {
  403. collected = append(collected, result)
  404. }
  405. }
  406. return collected, nil
  407. }