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