You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

extjson_reader.go 14KB

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