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  }