...

Source file src/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_reader.go

Documentation: go.mongodb.org/mongo-driver/bson/bsonrw

     1  // Copyright (C) MongoDB, Inc. 2017-present.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License"); you may
     4  // not use this file except in compliance with the License. You may obtain
     5  // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
     6  
     7  package bsonrw
     8  
     9  import (
    10  	"errors"
    11  	"fmt"
    12  	"io"
    13  	"sync"
    14  
    15  	"go.mongodb.org/mongo-driver/bson/bsontype"
    16  	"go.mongodb.org/mongo-driver/bson/primitive"
    17  )
    18  
    19  // ExtJSONValueReaderPool is a pool for ValueReaders that read ExtJSON.
    20  //
    21  // Deprecated: ExtJSONValueReaderPool will not be supported in Go Driver 2.0.
    22  type ExtJSONValueReaderPool struct {
    23  	pool sync.Pool
    24  }
    25  
    26  // NewExtJSONValueReaderPool instantiates a new ExtJSONValueReaderPool.
    27  //
    28  // Deprecated: ExtJSONValueReaderPool will not be supported in Go Driver 2.0.
    29  func NewExtJSONValueReaderPool() *ExtJSONValueReaderPool {
    30  	return &ExtJSONValueReaderPool{
    31  		pool: sync.Pool{
    32  			New: func() interface{} {
    33  				return new(extJSONValueReader)
    34  			},
    35  		},
    36  	}
    37  }
    38  
    39  // Get retrieves a ValueReader from the pool and uses src as the underlying ExtJSON.
    40  //
    41  // Deprecated: ExtJSONValueReaderPool will not be supported in Go Driver 2.0.
    42  func (bvrp *ExtJSONValueReaderPool) Get(r io.Reader, canonical bool) (ValueReader, error) {
    43  	vr := bvrp.pool.Get().(*extJSONValueReader)
    44  	return vr.reset(r, canonical)
    45  }
    46  
    47  // Put inserts a ValueReader into the pool. If the ValueReader is not a ExtJSON ValueReader nothing
    48  // is inserted into the pool and ok will be false.
    49  //
    50  // Deprecated: ExtJSONValueReaderPool will not be supported in Go Driver 2.0.
    51  func (bvrp *ExtJSONValueReaderPool) Put(vr ValueReader) (ok bool) {
    52  	bvr, ok := vr.(*extJSONValueReader)
    53  	if !ok {
    54  		return false
    55  	}
    56  
    57  	bvr, _ = bvr.reset(nil, false)
    58  	bvrp.pool.Put(bvr)
    59  	return true
    60  }
    61  
    62  type ejvrState struct {
    63  	mode  mode
    64  	vType bsontype.Type
    65  	depth int
    66  }
    67  
    68  // extJSONValueReader is for reading extended JSON.
    69  type extJSONValueReader struct {
    70  	p *extJSONParser
    71  
    72  	stack []ejvrState
    73  	frame int
    74  }
    75  
    76  // NewExtJSONValueReader creates a new ValueReader from a given io.Reader
    77  // It will interpret the JSON of r as canonical or relaxed according to the
    78  // given canonical flag
    79  func NewExtJSONValueReader(r io.Reader, canonical bool) (ValueReader, error) {
    80  	return newExtJSONValueReader(r, canonical)
    81  }
    82  
    83  func newExtJSONValueReader(r io.Reader, canonical bool) (*extJSONValueReader, error) {
    84  	ejvr := new(extJSONValueReader)
    85  	return ejvr.reset(r, canonical)
    86  }
    87  
    88  func (ejvr *extJSONValueReader) reset(r io.Reader, canonical bool) (*extJSONValueReader, error) {
    89  	p := newExtJSONParser(r, canonical)
    90  	typ, err := p.peekType()
    91  
    92  	if err != nil {
    93  		return nil, ErrInvalidJSON
    94  	}
    95  
    96  	var m mode
    97  	switch typ {
    98  	case bsontype.EmbeddedDocument:
    99  		m = mTopLevel
   100  	case bsontype.Array:
   101  		m = mArray
   102  	default:
   103  		m = mValue
   104  	}
   105  
   106  	stack := make([]ejvrState, 1, 5)
   107  	stack[0] = ejvrState{
   108  		mode:  m,
   109  		vType: typ,
   110  	}
   111  	return &extJSONValueReader{
   112  		p:     p,
   113  		stack: stack,
   114  	}, nil
   115  }
   116  
   117  func (ejvr *extJSONValueReader) advanceFrame() {
   118  	if ejvr.frame+1 >= len(ejvr.stack) { // We need to grow the stack
   119  		length := len(ejvr.stack)
   120  		if length+1 >= cap(ejvr.stack) {
   121  			// double it
   122  			buf := make([]ejvrState, 2*cap(ejvr.stack)+1)
   123  			copy(buf, ejvr.stack)
   124  			ejvr.stack = buf
   125  		}
   126  		ejvr.stack = ejvr.stack[:length+1]
   127  	}
   128  	ejvr.frame++
   129  
   130  	// Clean the stack
   131  	ejvr.stack[ejvr.frame].mode = 0
   132  	ejvr.stack[ejvr.frame].vType = 0
   133  	ejvr.stack[ejvr.frame].depth = 0
   134  }
   135  
   136  func (ejvr *extJSONValueReader) pushDocument() {
   137  	ejvr.advanceFrame()
   138  
   139  	ejvr.stack[ejvr.frame].mode = mDocument
   140  	ejvr.stack[ejvr.frame].depth = ejvr.p.depth
   141  }
   142  
   143  func (ejvr *extJSONValueReader) pushCodeWithScope() {
   144  	ejvr.advanceFrame()
   145  
   146  	ejvr.stack[ejvr.frame].mode = mCodeWithScope
   147  }
   148  
   149  func (ejvr *extJSONValueReader) pushArray() {
   150  	ejvr.advanceFrame()
   151  
   152  	ejvr.stack[ejvr.frame].mode = mArray
   153  }
   154  
   155  func (ejvr *extJSONValueReader) push(m mode, t bsontype.Type) {
   156  	ejvr.advanceFrame()
   157  
   158  	ejvr.stack[ejvr.frame].mode = m
   159  	ejvr.stack[ejvr.frame].vType = t
   160  }
   161  
   162  func (ejvr *extJSONValueReader) pop() {
   163  	switch ejvr.stack[ejvr.frame].mode {
   164  	case mElement, mValue:
   165  		ejvr.frame--
   166  	case mDocument, mArray, mCodeWithScope:
   167  		ejvr.frame -= 2 // we pop twice to jump over the vrElement: vrDocument -> vrElement -> vrDocument/TopLevel/etc...
   168  	}
   169  }
   170  
   171  func (ejvr *extJSONValueReader) skipObject() {
   172  	// read entire object until depth returns to 0 (last ending } or ] seen)
   173  	depth := 1
   174  	for depth > 0 {
   175  		ejvr.p.advanceState()
   176  
   177  		// If object is empty, raise depth and continue. When emptyObject is true, the
   178  		// parser has already read both the opening and closing brackets of an empty
   179  		// object ("{}"), so the next valid token will be part of the parent document,
   180  		// not part of the nested document.
   181  		//
   182  		// If there is a comma, there are remaining fields, emptyObject must be set back
   183  		// to false, and comma must be skipped with advanceState().
   184  		if ejvr.p.emptyObject {
   185  			if ejvr.p.s == jpsSawComma {
   186  				ejvr.p.emptyObject = false
   187  				ejvr.p.advanceState()
   188  			}
   189  			depth--
   190  			continue
   191  		}
   192  
   193  		switch ejvr.p.s {
   194  		case jpsSawBeginObject, jpsSawBeginArray:
   195  			depth++
   196  		case jpsSawEndObject, jpsSawEndArray:
   197  			depth--
   198  		}
   199  	}
   200  }
   201  
   202  func (ejvr *extJSONValueReader) invalidTransitionErr(destination mode, name string, modes []mode) error {
   203  	te := TransitionError{
   204  		name:        name,
   205  		current:     ejvr.stack[ejvr.frame].mode,
   206  		destination: destination,
   207  		modes:       modes,
   208  		action:      "read",
   209  	}
   210  	if ejvr.frame != 0 {
   211  		te.parent = ejvr.stack[ejvr.frame-1].mode
   212  	}
   213  	return te
   214  }
   215  
   216  func (ejvr *extJSONValueReader) typeError(t bsontype.Type) error {
   217  	return fmt.Errorf("positioned on %s, but attempted to read %s", ejvr.stack[ejvr.frame].vType, t)
   218  }
   219  
   220  func (ejvr *extJSONValueReader) ensureElementValue(t bsontype.Type, destination mode, callerName string, addModes ...mode) error {
   221  	switch ejvr.stack[ejvr.frame].mode {
   222  	case mElement, mValue:
   223  		if ejvr.stack[ejvr.frame].vType != t {
   224  			return ejvr.typeError(t)
   225  		}
   226  	default:
   227  		modes := []mode{mElement, mValue}
   228  		if addModes != nil {
   229  			modes = append(modes, addModes...)
   230  		}
   231  		return ejvr.invalidTransitionErr(destination, callerName, modes)
   232  	}
   233  
   234  	return nil
   235  }
   236  
   237  func (ejvr *extJSONValueReader) Type() bsontype.Type {
   238  	return ejvr.stack[ejvr.frame].vType
   239  }
   240  
   241  func (ejvr *extJSONValueReader) Skip() error {
   242  	switch ejvr.stack[ejvr.frame].mode {
   243  	case mElement, mValue:
   244  	default:
   245  		return ejvr.invalidTransitionErr(0, "Skip", []mode{mElement, mValue})
   246  	}
   247  
   248  	defer ejvr.pop()
   249  
   250  	t := ejvr.stack[ejvr.frame].vType
   251  	switch t {
   252  	case bsontype.Array, bsontype.EmbeddedDocument, bsontype.CodeWithScope:
   253  		// read entire array, doc or CodeWithScope
   254  		ejvr.skipObject()
   255  	default:
   256  		_, err := ejvr.p.readValue(t)
   257  		if err != nil {
   258  			return err
   259  		}
   260  	}
   261  
   262  	return nil
   263  }
   264  
   265  func (ejvr *extJSONValueReader) ReadArray() (ArrayReader, error) {
   266  	switch ejvr.stack[ejvr.frame].mode {
   267  	case mTopLevel: // allow reading array from top level
   268  	case mArray:
   269  		return ejvr, nil
   270  	default:
   271  		if err := ejvr.ensureElementValue(bsontype.Array, mArray, "ReadArray", mTopLevel, mArray); err != nil {
   272  			return nil, err
   273  		}
   274  	}
   275  
   276  	ejvr.pushArray()
   277  
   278  	return ejvr, nil
   279  }
   280  
   281  func (ejvr *extJSONValueReader) ReadBinary() (b []byte, btype byte, err error) {
   282  	if err := ejvr.ensureElementValue(bsontype.Binary, 0, "ReadBinary"); err != nil {
   283  		return nil, 0, err
   284  	}
   285  
   286  	v, err := ejvr.p.readValue(bsontype.Binary)
   287  	if err != nil {
   288  		return nil, 0, err
   289  	}
   290  
   291  	b, btype, err = v.parseBinary()
   292  
   293  	ejvr.pop()
   294  	return b, btype, err
   295  }
   296  
   297  func (ejvr *extJSONValueReader) ReadBoolean() (bool, error) {
   298  	if err := ejvr.ensureElementValue(bsontype.Boolean, 0, "ReadBoolean"); err != nil {
   299  		return false, err
   300  	}
   301  
   302  	v, err := ejvr.p.readValue(bsontype.Boolean)
   303  	if err != nil {
   304  		return false, err
   305  	}
   306  
   307  	if v.t != bsontype.Boolean {
   308  		return false, fmt.Errorf("expected type bool, but got type %s", v.t)
   309  	}
   310  
   311  	ejvr.pop()
   312  	return v.v.(bool), nil
   313  }
   314  
   315  func (ejvr *extJSONValueReader) ReadDocument() (DocumentReader, error) {
   316  	switch ejvr.stack[ejvr.frame].mode {
   317  	case mTopLevel:
   318  		return ejvr, nil
   319  	case mElement, mValue:
   320  		if ejvr.stack[ejvr.frame].vType != bsontype.EmbeddedDocument {
   321  			return nil, ejvr.typeError(bsontype.EmbeddedDocument)
   322  		}
   323  
   324  		ejvr.pushDocument()
   325  		return ejvr, nil
   326  	default:
   327  		return nil, ejvr.invalidTransitionErr(mDocument, "ReadDocument", []mode{mTopLevel, mElement, mValue})
   328  	}
   329  }
   330  
   331  func (ejvr *extJSONValueReader) ReadCodeWithScope() (code string, dr DocumentReader, err error) {
   332  	if err = ejvr.ensureElementValue(bsontype.CodeWithScope, 0, "ReadCodeWithScope"); err != nil {
   333  		return "", nil, err
   334  	}
   335  
   336  	v, err := ejvr.p.readValue(bsontype.CodeWithScope)
   337  	if err != nil {
   338  		return "", nil, err
   339  	}
   340  
   341  	code, err = v.parseJavascript()
   342  
   343  	ejvr.pushCodeWithScope()
   344  	return code, ejvr, err
   345  }
   346  
   347  func (ejvr *extJSONValueReader) ReadDBPointer() (ns string, oid primitive.ObjectID, err error) {
   348  	if err = ejvr.ensureElementValue(bsontype.DBPointer, 0, "ReadDBPointer"); err != nil {
   349  		return "", primitive.NilObjectID, err
   350  	}
   351  
   352  	v, err := ejvr.p.readValue(bsontype.DBPointer)
   353  	if err != nil {
   354  		return "", primitive.NilObjectID, err
   355  	}
   356  
   357  	ns, oid, err = v.parseDBPointer()
   358  
   359  	ejvr.pop()
   360  	return ns, oid, err
   361  }
   362  
   363  func (ejvr *extJSONValueReader) ReadDateTime() (int64, error) {
   364  	if err := ejvr.ensureElementValue(bsontype.DateTime, 0, "ReadDateTime"); err != nil {
   365  		return 0, err
   366  	}
   367  
   368  	v, err := ejvr.p.readValue(bsontype.DateTime)
   369  	if err != nil {
   370  		return 0, err
   371  	}
   372  
   373  	d, err := v.parseDateTime()
   374  
   375  	ejvr.pop()
   376  	return d, err
   377  }
   378  
   379  func (ejvr *extJSONValueReader) ReadDecimal128() (primitive.Decimal128, error) {
   380  	if err := ejvr.ensureElementValue(bsontype.Decimal128, 0, "ReadDecimal128"); err != nil {
   381  		return primitive.Decimal128{}, err
   382  	}
   383  
   384  	v, err := ejvr.p.readValue(bsontype.Decimal128)
   385  	if err != nil {
   386  		return primitive.Decimal128{}, err
   387  	}
   388  
   389  	d, err := v.parseDecimal128()
   390  
   391  	ejvr.pop()
   392  	return d, err
   393  }
   394  
   395  func (ejvr *extJSONValueReader) ReadDouble() (float64, error) {
   396  	if err := ejvr.ensureElementValue(bsontype.Double, 0, "ReadDouble"); err != nil {
   397  		return 0, err
   398  	}
   399  
   400  	v, err := ejvr.p.readValue(bsontype.Double)
   401  	if err != nil {
   402  		return 0, err
   403  	}
   404  
   405  	d, err := v.parseDouble()
   406  
   407  	ejvr.pop()
   408  	return d, err
   409  }
   410  
   411  func (ejvr *extJSONValueReader) ReadInt32() (int32, error) {
   412  	if err := ejvr.ensureElementValue(bsontype.Int32, 0, "ReadInt32"); err != nil {
   413  		return 0, err
   414  	}
   415  
   416  	v, err := ejvr.p.readValue(bsontype.Int32)
   417  	if err != nil {
   418  		return 0, err
   419  	}
   420  
   421  	i, err := v.parseInt32()
   422  
   423  	ejvr.pop()
   424  	return i, err
   425  }
   426  
   427  func (ejvr *extJSONValueReader) ReadInt64() (int64, error) {
   428  	if err := ejvr.ensureElementValue(bsontype.Int64, 0, "ReadInt64"); err != nil {
   429  		return 0, err
   430  	}
   431  
   432  	v, err := ejvr.p.readValue(bsontype.Int64)
   433  	if err != nil {
   434  		return 0, err
   435  	}
   436  
   437  	i, err := v.parseInt64()
   438  
   439  	ejvr.pop()
   440  	return i, err
   441  }
   442  
   443  func (ejvr *extJSONValueReader) ReadJavascript() (code string, err error) {
   444  	if err = ejvr.ensureElementValue(bsontype.JavaScript, 0, "ReadJavascript"); err != nil {
   445  		return "", err
   446  	}
   447  
   448  	v, err := ejvr.p.readValue(bsontype.JavaScript)
   449  	if err != nil {
   450  		return "", err
   451  	}
   452  
   453  	code, err = v.parseJavascript()
   454  
   455  	ejvr.pop()
   456  	return code, err
   457  }
   458  
   459  func (ejvr *extJSONValueReader) ReadMaxKey() error {
   460  	if err := ejvr.ensureElementValue(bsontype.MaxKey, 0, "ReadMaxKey"); err != nil {
   461  		return err
   462  	}
   463  
   464  	v, err := ejvr.p.readValue(bsontype.MaxKey)
   465  	if err != nil {
   466  		return err
   467  	}
   468  
   469  	err = v.parseMinMaxKey("max")
   470  
   471  	ejvr.pop()
   472  	return err
   473  }
   474  
   475  func (ejvr *extJSONValueReader) ReadMinKey() error {
   476  	if err := ejvr.ensureElementValue(bsontype.MinKey, 0, "ReadMinKey"); err != nil {
   477  		return err
   478  	}
   479  
   480  	v, err := ejvr.p.readValue(bsontype.MinKey)
   481  	if err != nil {
   482  		return err
   483  	}
   484  
   485  	err = v.parseMinMaxKey("min")
   486  
   487  	ejvr.pop()
   488  	return err
   489  }
   490  
   491  func (ejvr *extJSONValueReader) ReadNull() error {
   492  	if err := ejvr.ensureElementValue(bsontype.Null, 0, "ReadNull"); err != nil {
   493  		return err
   494  	}
   495  
   496  	v, err := ejvr.p.readValue(bsontype.Null)
   497  	if err != nil {
   498  		return err
   499  	}
   500  
   501  	if v.t != bsontype.Null {
   502  		return fmt.Errorf("expected type null but got type %s", v.t)
   503  	}
   504  
   505  	ejvr.pop()
   506  	return nil
   507  }
   508  
   509  func (ejvr *extJSONValueReader) ReadObjectID() (primitive.ObjectID, error) {
   510  	if err := ejvr.ensureElementValue(bsontype.ObjectID, 0, "ReadObjectID"); err != nil {
   511  		return primitive.ObjectID{}, err
   512  	}
   513  
   514  	v, err := ejvr.p.readValue(bsontype.ObjectID)
   515  	if err != nil {
   516  		return primitive.ObjectID{}, err
   517  	}
   518  
   519  	oid, err := v.parseObjectID()
   520  
   521  	ejvr.pop()
   522  	return oid, err
   523  }
   524  
   525  func (ejvr *extJSONValueReader) ReadRegex() (pattern string, options string, err error) {
   526  	if err = ejvr.ensureElementValue(bsontype.Regex, 0, "ReadRegex"); err != nil {
   527  		return "", "", err
   528  	}
   529  
   530  	v, err := ejvr.p.readValue(bsontype.Regex)
   531  	if err != nil {
   532  		return "", "", err
   533  	}
   534  
   535  	pattern, options, err = v.parseRegex()
   536  
   537  	ejvr.pop()
   538  	return pattern, options, err
   539  }
   540  
   541  func (ejvr *extJSONValueReader) ReadString() (string, error) {
   542  	if err := ejvr.ensureElementValue(bsontype.String, 0, "ReadString"); err != nil {
   543  		return "", err
   544  	}
   545  
   546  	v, err := ejvr.p.readValue(bsontype.String)
   547  	if err != nil {
   548  		return "", err
   549  	}
   550  
   551  	if v.t != bsontype.String {
   552  		return "", fmt.Errorf("expected type string but got type %s", v.t)
   553  	}
   554  
   555  	ejvr.pop()
   556  	return v.v.(string), nil
   557  }
   558  
   559  func (ejvr *extJSONValueReader) ReadSymbol() (symbol string, err error) {
   560  	if err = ejvr.ensureElementValue(bsontype.Symbol, 0, "ReadSymbol"); err != nil {
   561  		return "", err
   562  	}
   563  
   564  	v, err := ejvr.p.readValue(bsontype.Symbol)
   565  	if err != nil {
   566  		return "", err
   567  	}
   568  
   569  	symbol, err = v.parseSymbol()
   570  
   571  	ejvr.pop()
   572  	return symbol, err
   573  }
   574  
   575  func (ejvr *extJSONValueReader) ReadTimestamp() (t uint32, i uint32, err error) {
   576  	if err = ejvr.ensureElementValue(bsontype.Timestamp, 0, "ReadTimestamp"); err != nil {
   577  		return 0, 0, err
   578  	}
   579  
   580  	v, err := ejvr.p.readValue(bsontype.Timestamp)
   581  	if err != nil {
   582  		return 0, 0, err
   583  	}
   584  
   585  	t, i, err = v.parseTimestamp()
   586  
   587  	ejvr.pop()
   588  	return t, i, err
   589  }
   590  
   591  func (ejvr *extJSONValueReader) ReadUndefined() error {
   592  	if err := ejvr.ensureElementValue(bsontype.Undefined, 0, "ReadUndefined"); err != nil {
   593  		return err
   594  	}
   595  
   596  	v, err := ejvr.p.readValue(bsontype.Undefined)
   597  	if err != nil {
   598  		return err
   599  	}
   600  
   601  	err = v.parseUndefined()
   602  
   603  	ejvr.pop()
   604  	return err
   605  }
   606  
   607  func (ejvr *extJSONValueReader) ReadElement() (string, ValueReader, error) {
   608  	switch ejvr.stack[ejvr.frame].mode {
   609  	case mTopLevel, mDocument, mCodeWithScope:
   610  	default:
   611  		return "", nil, ejvr.invalidTransitionErr(mElement, "ReadElement", []mode{mTopLevel, mDocument, mCodeWithScope})
   612  	}
   613  
   614  	name, t, err := ejvr.p.readKey()
   615  
   616  	if err != nil {
   617  		if errors.Is(err, ErrEOD) {
   618  			if ejvr.stack[ejvr.frame].mode == mCodeWithScope {
   619  				_, err := ejvr.p.peekType()
   620  				if err != nil {
   621  					return "", nil, err
   622  				}
   623  			}
   624  
   625  			ejvr.pop()
   626  		}
   627  
   628  		return "", nil, err
   629  	}
   630  
   631  	ejvr.push(mElement, t)
   632  	return name, ejvr, nil
   633  }
   634  
   635  func (ejvr *extJSONValueReader) ReadValue() (ValueReader, error) {
   636  	switch ejvr.stack[ejvr.frame].mode {
   637  	case mArray:
   638  	default:
   639  		return nil, ejvr.invalidTransitionErr(mValue, "ReadValue", []mode{mArray})
   640  	}
   641  
   642  	t, err := ejvr.p.peekType()
   643  	if err != nil {
   644  		if errors.Is(err, ErrEOA) {
   645  			ejvr.pop()
   646  		}
   647  
   648  		return nil, err
   649  	}
   650  
   651  	ejvr.push(mValue, t)
   652  	return ejvr, nil
   653  }
   654  

View as plain text