extjson_reader.go raw

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