github.com/goshafaq/sonic@v0.0.0-20231026082336-871835fb94c6/ast/iterator.go (about) 1 /* 2 * Copyright 2021 ByteDance Inc. 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 ast 18 19 import ( 20 "fmt" 21 22 "github.com/goshafaq/sonic/internal/native/types" 23 ) 24 25 type Pair struct { 26 Key string 27 Value Node 28 } 29 30 // Values returns iterator for array's children traversal 31 func (self *Node) Values() (ListIterator, error) { 32 if err := self.should(types.V_ARRAY, "an array"); err != nil { 33 return ListIterator{}, err 34 } 35 return ListIterator{Iterator{p: self}}, nil 36 } 37 38 // Properties returns iterator for object's children traversal 39 func (self *Node) Properties() (ObjectIterator, error) { 40 if err := self.should(types.V_OBJECT, "an object"); err != nil { 41 return ObjectIterator{}, err 42 } 43 return ObjectIterator{Iterator{p: self}}, nil 44 } 45 46 type Iterator struct { 47 i int 48 p *Node 49 } 50 51 func (self *Iterator) Pos() int { 52 return self.i 53 } 54 55 func (self *Iterator) Len() int { 56 return self.p.len() 57 } 58 59 // HasNext reports if it is the end of iteration or has error. 60 func (self *Iterator) HasNext() bool { 61 if !self.p.isLazy() { 62 return self.p.Valid() && self.i < self.p.len() 63 } else if self.p.t == _V_ARRAY_LAZY { 64 return self.p.skipNextNode().Valid() 65 } else if self.p.t == _V_OBJECT_LAZY { 66 pair := self.p.skipNextPair() 67 if pair == nil { 68 return false 69 } 70 return pair.Value.Valid() 71 } 72 return false 73 } 74 75 // ListIterator is specialized iterator for V_ARRAY 76 type ListIterator struct { 77 Iterator 78 } 79 80 // ObjectIterator is specialized iterator for V_ARRAY 81 type ObjectIterator struct { 82 Iterator 83 } 84 85 func (self *ListIterator) next() *Node { 86 next_start: 87 if !self.HasNext() { 88 return nil 89 } else { 90 n := self.p.nodeAt(self.i) 91 self.i++ 92 if !n.Exists() { 93 goto next_start 94 } 95 return n 96 } 97 } 98 99 // Next scans through children of underlying V_ARRAY, 100 // copies each child to v, and returns .HasNext(). 101 func (self *ListIterator) Next(v *Node) bool { 102 n := self.next() 103 if n == nil { 104 return false 105 } 106 *v = *n 107 return true 108 } 109 110 func (self *ObjectIterator) next() *Pair { 111 next_start: 112 if !self.HasNext() { 113 return nil 114 } else { 115 n := self.p.pairAt(self.i) 116 self.i++ 117 if !n.Value.Exists() { 118 goto next_start 119 } 120 return n 121 } 122 } 123 124 // Next scans through children of underlying V_OBJECT, 125 // copies each child to v, and returns .HasNext(). 126 func (self *ObjectIterator) Next(p *Pair) bool { 127 n := self.next() 128 if n == nil { 129 return false 130 } 131 *p = *n 132 return true 133 } 134 135 // Sequence represents scanning path of single-layer nodes. 136 // Index indicates the value's order in both V_ARRAY and V_OBJECT json. 137 // Key is the value's key (for V_OBJECT json only, otherwise it will be nil). 138 type Sequence struct { 139 Index int 140 Key *string 141 // Level int 142 } 143 144 // String is string representation of one Sequence 145 func (s Sequence) String() string { 146 k := "" 147 if s.Key != nil { 148 k = *s.Key 149 } 150 return fmt.Sprintf("Sequence(%d, %q)", s.Index, k) 151 } 152 153 type Scanner func(path Sequence, node *Node) bool 154 155 // ForEach scans one V_OBJECT node's children from JSON head to tail, 156 // and pass the Sequence and Node of corresponding JSON value. 157 // 158 // Especailly, if the node is not V_ARRAY or V_OBJECT, 159 // the node itself will be returned and Sequence.Index == -1. 160 // 161 // NOTICE: A unsetted node WON'T trigger sc, but its index still counts into Path.Index 162 func (self *Node) ForEach(sc Scanner) error { 163 switch self.itype() { 164 case types.V_ARRAY: 165 iter, err := self.Values() 166 if err != nil { 167 return err 168 } 169 v := iter.next() 170 for v != nil { 171 if !sc(Sequence{iter.i - 1, nil}, v) { 172 return nil 173 } 174 v = iter.next() 175 } 176 case types.V_OBJECT: 177 iter, err := self.Properties() 178 if err != nil { 179 return err 180 } 181 v := iter.next() 182 for v != nil { 183 if !sc(Sequence{iter.i - 1, &v.Key}, &v.Value) { 184 return nil 185 } 186 v = iter.next() 187 } 188 default: 189 if self.Check() != nil { 190 return self 191 } 192 sc(Sequence{-1, nil}, self) 193 } 194 return nil 195 }