1 
2 /**
3  *    Copyright (C) 2018-present MongoDB, Inc.
4  *
5  *    This program is free software: you can redistribute it and/or modify
6  *    it under the terms of the Server Side Public License, version 1,
7  *    as published by MongoDB, Inc.
8  *
9  *    This program is distributed in the hope that it will be useful,
10  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *    Server Side Public License for more details.
13  *
14  *    You should have received a copy of the Server Side Public License
15  *    along with this program. If not, see
16  *    <http://www.mongodb.com/licensing/server-side-public-license>.
17  *
18  *    As a special exception, the copyright holders give permission to link the
19  *    code of portions of this program with the OpenSSL library under certain
20  *    conditions as described in each individual source file and distribute
21  *    linked combinations including the program with the OpenSSL library. You
22  *    must comply with the Server Side Public License in all respects for
23  *    all of the code used other than as permitted herein. If you modify file(s)
24  *    with this exception, you may extend this exception to your version of the
25  *    file(s), but you are not obligated to do so. If you do not wish to do so,
26  *    delete this exception statement from your version. If you delete this
27  *    exception statement from all source files in the program, then also delete
28  *    it in the license file.
29  */
30 
31 #pragma once
32 
33 #include "mongo/db/pipeline/document_internal.h"
34 
35 #include <boost/functional/hash.hpp>
36 #include <boost/intrusive_ptr.hpp>
37 
38 #include "mongo/base/string_data.h"
39 #include "mongo/base/string_data_comparator_interface.h"
40 #include "mongo/bson/util/builder.h"
41 
42 namespace mongo {
43 class BSONObj;
44 class FieldIterator;
45 class FieldPath;
46 class Value;
47 class MutableDocument;
48 
49 /** An internal class that represents the position of a field in a document.
50  *
51  *  This is a low-level class that you usually don't need to worry about.
52  *
53  *  The main use of this class for clients is to allow refetching or
54  *  setting a field without looking it up again. It has a default
55  *  constructor that represents a field not being in a document. It also
56  *  has a method 'bool found()' that tells you if a field was found.
57  *
58  *  For more details see document_internal.h
59  */
60 class Position;
61 
62 /** A Document is similar to a BSONObj but with a different in-memory representation.
63  *
64  *  A Document can be treated as a const std::map<std::string, const Value> that is
65  *  very cheap to copy and is Assignable.  Therefore, it is acceptable to
66  *  pass and return by Value. Note that the data in a Document is
67  *  immutable, but you can replace a Document instance with assignment.
68  *
69  *  See Also: Value class in Value.h
70  */
71 class Document {
72 public:
73     /**
74      * Operator overloads for relops return a DeferredComparison which can subsequently be evaluated
75      * by a DocumentComparator.
76      */
77     struct DeferredComparison {
78         enum class Type {
79             kLT,
80             kLTE,
81             kEQ,
82             kGT,
83             kGTE,
84             kNE,
85         };
86 
DeferredComparisonDeferredComparison87         DeferredComparison(Type type, const Document& lhs, const Document& rhs)
88             : type(type), lhs(lhs), rhs(rhs) {}
89 
90         Type type;
91         const Document& lhs;
92         const Document& rhs;
93     };
94 
95     static constexpr StringData metaFieldTextScore = "$textScore"_sd;
96     static constexpr StringData metaFieldRandVal = "$randVal"_sd;
97     static constexpr StringData metaFieldSortKey = "$sortKey"_sd;
98 
99     static const std::vector<StringData> allMetadataFieldNames;
100 
101     /// Empty Document (does no allocation)
Document()102     Document() {}
103 
104     /// Create a new Document deep-converted from the given BSONObj.
105     explicit Document(const BSONObj& bson);
106 
107     /**
108      * Create a new document from key, value pairs. Enables constructing a document using this
109      * syntax:
110      * auto document = Document{{"hello", "world"}, {"number": 1}};
111      */
112     Document(std::initializer_list<std::pair<StringData, ImplicitValue>> initializerList);
113 
swap(Document & rhs)114     void swap(Document& rhs) {
115         _storage.swap(rhs._storage);
116     }
117 
118     /// Look up a field by key name. Returns Value() if no such field. O(1)
119     const Value operator[](StringData key) const {
120         return getField(key);
121     }
getField(StringData key)122     const Value getField(StringData key) const {
123         return storage().getField(key);
124     }
125 
126     /// Look up a field by Position. See positionOf and getNestedField.
127     const Value operator[](Position pos) const {
128         return getField(pos);
129     }
getField(Position pos)130     const Value getField(Position pos) const {
131         return storage().getField(pos).val;
132     }
133 
134     /**
135      * Returns the Value stored at the location given by 'path', or Value() if no such path exists.
136      * If 'positions' is non-null, it will be filled with a path suitable to pass to
137      * MutableDocument::setNestedField().
138      */
139     const Value getNestedField(const FieldPath& path,
140                                std::vector<Position>* positions = nullptr) const;
141 
142     /// Number of fields in this document. O(n)
size()143     size_t size() const {
144         return storage().size();
145     }
146 
147     /// True if this document has no fields.
empty()148     bool empty() const {
149         return !_storage || storage().iterator().atEnd();
150     }
151 
152     /// Create a new FieldIterator that can be used to examine the Document's fields in order.
153     FieldIterator fieldIterator() const;
154 
155     /// Convenience type for dealing with fields. Used by FieldIterator.
156     typedef std::pair<StringData, Value> FieldPair;
157 
158     /** Get the approximate storage size of the document and sub-values in bytes.
159      *  Note: Some memory may be shared with other Documents or between fields within
160      *        a single Document so this can overestimate usage.
161      */
162     size_t getApproximateSize() const;
163 
164     /**
165      * Compare two documents. Most callers should prefer using DocumentComparator instead. See
166      * document_comparator.h for details.
167      *
168      *  BSON document field order is significant, so this just goes through
169      *  the fields in order.  The comparison is done in roughly the same way
170      *  as strings are compared, but comparing one field at a time instead
171      *  of one character at a time.
172      *
173      *  Pass a non-null StringData::ComparatorInterface if special string comparison semantics are
174      *  required. If the comparator is null, then a simple binary compare is used for strings. This
175      *  comparator is only used for string *values*; field names are always compared using simple
176      *  binary compare.
177      *
178      *  Note: This does not consider metadata when comparing documents.
179      *
180      *  @returns an integer less than zero, zero, or an integer greater than
181      *           zero, depending on whether lhs < rhs, lhs == rhs, or lhs > rhs
182      *  Warning: may return values other than -1, 0, or 1
183      */
184     static int compare(const Document& lhs,
185                        const Document& rhs,
186                        const StringData::ComparatorInterface* stringComparator);
187 
188     std::string toString() const;
189 
190     friend std::ostream& operator<<(std::ostream& out, const Document& doc) {
191         return out << doc.toString();
192     }
193 
194     /** Calculate a hash value.
195      *
196      * Meant to be used to create composite hashes suitable for
197      * hashed container classes such as unordered_map.
198      */
199     void hash_combine(size_t& seed, const StringData::ComparatorInterface* stringComparator) const;
200 
201     /**
202      * Serializes this document to the BSONObj under construction in 'builder'. Metadata is not
203      * included. Throws a AssertionException if 'recursionLevel' exceeds the maximum allowable
204      * depth.
205      */
206     void toBson(BSONObjBuilder* builder, size_t recursionLevel = 1) const;
207     BSONObj toBson() const;
208 
209     /**
210      * Like toBson, but includes metadata at the top-level.
211      * Output is parseable by fromBsonWithMetaData
212      */
213     BSONObj toBsonWithMetaData(bool includeSortKey = true) const;
214 
215     /**
216      * Like Document(BSONObj) but treats top-level fields with special names as metadata.
217      * Special field names are available as static constants on this class with names starting
218      * with metaField.
219      */
220     static Document fromBsonWithMetaData(const BSONObj& bson);
221 
222     /**
223      * Given a BSON object that may have metadata fields added as part of toBsonWithMetadata(),
224      * returns the same object without any of the metadata fields.
225      */
226     static BSONObj stripMetadataFields(const BSONObj& bsonWithMetadata);
227 
228     // Support BSONObjBuilder and BSONArrayBuilder "stream" API
229     friend BSONObjBuilder& operator<<(BSONObjBuilderValueStream& builder, const Document& d);
230 
231     /** Return the abstract Position of a field, suitable to pass to operator[] or getField().
232      *  This can potentially save time if you need to refer to a field multiple times.
233      */
positionOf(StringData fieldName)234     Position positionOf(StringData fieldName) const {
235         return storage().findField(fieldName);
236     }
237 
238     /** Clone a document.
239      *
240      *  This should only be called by MutableDocument and tests
241      *
242      *  The new document shares all the fields' values with the original.
243      *  This is not a deep copy.  Only the fields on the top-level document
244      *  are cloned.
245      */
clone()246     Document clone() const {
247         return Document(storage().clone().get());
248     }
249 
hasTextScore()250     bool hasTextScore() const {
251         return storage().hasTextScore();
252     }
getTextScore()253     double getTextScore() const {
254         return storage().getTextScore();
255     }
256 
hasRandMetaField()257     bool hasRandMetaField() const {
258         return storage().hasRandMetaField();
259     }
getRandMetaField()260     double getRandMetaField() const {
261         return storage().getRandMetaField();
262     }
263 
hasSortKeyMetaField()264     bool hasSortKeyMetaField() const {
265         return storage().hasSortKeyMetaField();
266     }
getSortKeyMetaField()267     BSONObj getSortKeyMetaField() const {
268         return storage().getSortKeyMetaField();
269     }
270 
271     /// members for Sorter
272     struct SorterDeserializeSettings {};  // unused
273     void serializeForSorter(BufBuilder& buf) const;
274     static Document deserializeForSorter(BufReader& buf, const SorterDeserializeSettings&);
memUsageForSorter()275     int memUsageForSorter() const {
276         return getApproximateSize();
277     }
getOwned()278     Document getOwned() const {
279         return *this;
280     }
281 
282     /// only for testing
getPtr()283     const void* getPtr() const {
284         return _storage.get();
285     }
286 
287 private:
288     friend class FieldIterator;
289     friend class ValueStorage;
290     friend class MutableDocument;
291     friend class MutableValue;
292 
Document(const DocumentStorage * ptr)293     explicit Document(const DocumentStorage* ptr) : _storage(ptr){};
294 
storage()295     const DocumentStorage& storage() const {
296         return (_storage ? *_storage : DocumentStorage::emptyDoc());
297     }
298     boost::intrusive_ptr<const DocumentStorage> _storage;
299 };
300 
301 //
302 // Comparison API.
303 //
304 // Document instances can be compared either using Document::compare() or via operator overloads.
305 // Most callers should prefer operator overloads. Note that the operator overloads return a
306 // DeferredComparison, which must be subsequently evaluated by a DocumentComparator. See
307 // document_comparator.h for details.
308 //
309 
310 inline Document::DeferredComparison operator==(const Document& lhs, const Document& rhs) {
311     return Document::DeferredComparison(Document::DeferredComparison::Type::kEQ, lhs, rhs);
312 }
313 
314 inline Document::DeferredComparison operator!=(const Document& lhs, const Document& rhs) {
315     return Document::DeferredComparison(Document::DeferredComparison::Type::kNE, lhs, rhs);
316 }
317 
318 inline Document::DeferredComparison operator<(const Document& lhs, const Document& rhs) {
319     return Document::DeferredComparison(Document::DeferredComparison::Type::kLT, lhs, rhs);
320 }
321 
322 inline Document::DeferredComparison operator<=(const Document& lhs, const Document& rhs) {
323     return Document::DeferredComparison(Document::DeferredComparison::Type::kLTE, lhs, rhs);
324 }
325 
326 inline Document::DeferredComparison operator>(const Document& lhs, const Document& rhs) {
327     return Document::DeferredComparison(Document::DeferredComparison::Type::kGT, lhs, rhs);
328 }
329 
330 inline Document::DeferredComparison operator>=(const Document& lhs, const Document& rhs) {
331     return Document::DeferredComparison(Document::DeferredComparison::Type::kGTE, lhs, rhs);
332 }
333 
334 /** This class is returned by MutableDocument to allow you to modify its values.
335  *  You are not allowed to hold variables of this type (enforced by the type system).
336  */
337 class MutableValue {
338 public:
339     void operator=(const Value& v) {
340         _val = v;
341     }
342 
343     void operator=(Value&& v) {
344         _val = std::move(v);
345     }
346 
347     /** These are designed to allow things like mutDoc["a"]["b"]["c"] = Value(10);
348      *  It is safe to use even on nonexistent fields.
349      */
350     MutableValue operator[](StringData key) {
351         return getField(key);
352     }
353     MutableValue operator[](Position pos) {
354         return getField(pos);
355     }
356 
357     MutableValue getField(StringData key);
358     MutableValue getField(Position pos);
359 
360 private:
361     friend class MutableDocument;
362 
363     /// can only be constructed or copied by self and friends
MutableValue(const MutableValue & other)364     MutableValue(const MutableValue& other) : _val(other._val) {}
MutableValue(Value & val)365     explicit MutableValue(Value& val) : _val(val) {}
366 
367     /// Used by MutableDocument(MutableValue)
getDocPtr()368     const RefCountable*& getDocPtr() {
369         if (_val.getType() != Object || _val._storage.genericRCPtr == NULL) {
370             // If the current value isn't an object we replace it with a Object-typed Value.
371             // Note that we can't just use Document() here because that is a NULL pointer and
372             // Value doesn't refcount NULL pointers. This led to a memory leak (SERVER-10554)
373             // because MutableDocument::newStorage() would set a non-NULL pointer into the Value
374             // without setting the refCounter bit. While allocating a DocumentStorage here could
375             // result in an allocation where none is needed, in practice this is only called
376             // when we are about to add a field to the sub-document so this just changes where
377             // the allocation is done.
378             _val = Value(Document(new DocumentStorage()));
379         }
380 
381         return _val._storage.genericRCPtr;
382     }
383 
384     MutableValue& operator=(const MutableValue&);  // not assignable with another MutableValue
385 
386     Value& _val;
387 };
388 
389 /** MutableDocument is a Document builder that supports both adding and updating fields.
390  *
391  *  This class fills a similar role to BSONObjBuilder, but allows you to
392  *  change existing fields and more easily write to sub-Documents.
393  *
394  *  To preserve the immutability of Documents, MutableDocument will
395  *  shallow-clone its storage on write (COW) if it is shared with any other
396  *  Documents.
397  */
398 class MutableDocument {
399     MONGO_DISALLOW_COPYING(MutableDocument);
400 
401 public:
402     /** Create a new empty Document.
403      *
404      *  @param expectedFields a hint at what the number of fields will be, if known.
405      *         this can be used to increase memory allocation efficiency. There is
406      *         no impact on correctness if this field over or under estimates.
407      *
408      *  TODO: find some way to convey field-name sizes to make even more efficient
409      */
MutableDocument()410     MutableDocument() : _storageHolder(NULL), _storage(_storageHolder) {}
411     explicit MutableDocument(size_t expectedFields);
412 
413     /// No copy of data yet. Copy-on-write. See storage()
MutableDocument(Document d)414     explicit MutableDocument(Document d) : _storageHolder(NULL), _storage(_storageHolder) {
415         reset(std::move(d));
416     }
417 
~MutableDocument()418     ~MutableDocument() {
419         if (_storageHolder)
420             intrusive_ptr_release(_storageHolder);
421     }
422 
423     /** Replace the current base Document with the argument
424      *
425      *  All Positions from the passed in Document are valid and refer to the
426      *  same field in this MutableDocument.
427      */
428     void reset(Document d = Document()) {
429         reset(std::move(d._storage));
430     }
431 
432     /** Add the given field to the Document.
433      *
434      *  BSON documents' fields are ordered; the new Field will be
435      *  appended to the current list of fields.
436      *
437      *  Unlike getField/setField, addField does not look for a field with the
438      *  same name and therefore cannot be used to update fields.
439      *
440      *  It is an error to add a field that has the same name as another field.
441      *
442      *  TODO: This is currently allowed but getField only gets first field.
443      *        Decide what level of support is needed for duplicate fields.
444      *        If duplicates are not allowed, consider removing this method.
445      */
addField(StringData fieldName,const Value & val)446     void addField(StringData fieldName, const Value& val) {
447         storage().appendField(fieldName) = val;
448     }
449 
450     /** Update field by key. If there is no field with that key, add one.
451      *
452      *  If the new value is missing(), the field is logically removed.
453      */
454     MutableValue operator[](StringData key) {
455         return getField(key);
456     }
setField(StringData key,const Value & val)457     void setField(StringData key, const Value& val) {
458         getField(key) = val;
459     }
getField(StringData key)460     MutableValue getField(StringData key) {
461         return MutableValue(storage().getField(key));
462     }
463 
464     /// Update field by Position. Must already be a valid Position.
465     MutableValue operator[](Position pos) {
466         return getField(pos);
467     }
setField(Position pos,const Value & val)468     void setField(Position pos, const Value& val) {
469         getField(pos) = val;
470     }
getField(Position pos)471     MutableValue getField(Position pos) {
472         return MutableValue(storage().getField(pos).val);
473     }
474 
475     /// Logically remove a field. Note that memory usage does not decrease.
remove(StringData key)476     void remove(StringData key) {
477         getField(key) = Value();
478     }
removeNestedField(const std::vector<Position> & positions)479     void removeNestedField(const std::vector<Position>& positions) {
480         getNestedField(positions) = Value();
481     }
482 
483     /** Gets/Sets a nested field given a path.
484      *
485      *  All fields along path are created as empty Documents if they don't exist
486      *  or are any other type.
487      */
488     MutableValue getNestedField(const FieldPath& dottedField);
setNestedField(const FieldPath & dottedField,const Value & val)489     void setNestedField(const FieldPath& dottedField, const Value& val) {
490         getNestedField(dottedField) = val;
491     }
492 
493     /// Takes positions vector from Document::getNestedField. All fields in path must exist.
494     MutableValue getNestedField(const std::vector<Position>& positions);
setNestedField(const std::vector<Position> & positions,const Value & val)495     void setNestedField(const std::vector<Position>& positions, const Value& val) {
496         getNestedField(positions) = val;
497     }
498 
499     /**
500      * Copies all metadata from source if it has any.
501      * Note: does not clear metadata from this.
502      */
copyMetaDataFrom(const Document & source)503     void copyMetaDataFrom(const Document& source) {
504         storage().copyMetaDataFrom(source.storage());
505     }
506 
setTextScore(double score)507     void setTextScore(double score) {
508         storage().setTextScore(score);
509     }
510 
setRandMetaField(double val)511     void setRandMetaField(double val) {
512         storage().setRandMetaField(val);
513     }
514 
setSortKeyMetaField(BSONObj sortKey)515     void setSortKeyMetaField(BSONObj sortKey) {
516         storage().setSortKeyMetaField(sortKey);
517     }
518 
519     /** Convert to a read-only document and release reference.
520      *
521      *  Call this to indicate that you are done with this Document and will
522      *  not be making further changes from this MutableDocument.
523      *
524      *  TODO: there are some optimizations that may make sense at freeze time.
525      */
freeze()526     Document freeze() {
527         // This essentially moves _storage into a new Document by way of temp.
528         Document ret;
529         boost::intrusive_ptr<const DocumentStorage> temp(storagePtr(), /*inc_ref_count=*/false);
530         temp.swap(ret._storage);
531         _storage = NULL;
532         return ret;
533     }
534 
535     /// Used to simplify the common pattern of creating a value of the document.
freezeToValue()536     Value freezeToValue() {
537         return Value(freeze());
538     }
539 
540     /** Borrow a readable reference to this Document.
541      *
542      *  Note that unlike freeze(), this indicates intention to continue
543      *  modifying this document. The returned Document will not observe
544      *  future changes to this MutableDocument.
545      */
peek()546     Document peek() {
547         return Document(storagePtr());
548     }
549 
getApproximateSize()550     size_t getApproximateSize() {
551         return peek().getApproximateSize();
552     }
553 
554 private:
555     friend class MutableValue;  // for access to next constructor
MutableDocument(MutableValue mv)556     explicit MutableDocument(MutableValue mv) : _storageHolder(NULL), _storage(mv.getDocPtr()) {}
557 
reset(boost::intrusive_ptr<const DocumentStorage> ds)558     void reset(boost::intrusive_ptr<const DocumentStorage> ds) {
559         if (_storage)
560             intrusive_ptr_release(_storage);
561         _storage = ds.detach();
562     }
563 
564     // This is split into 3 functions to speed up the fast-path
storage()565     DocumentStorage& storage() {
566         if (MONGO_unlikely(!_storage))
567             return newStorage();
568 
569         if (MONGO_unlikely(_storage->isShared()))
570             return clonedStorage();
571 
572         // This function exists to ensure this is safe
573         return const_cast<DocumentStorage&>(*storagePtr());
574     }
newStorage()575     DocumentStorage& newStorage() {
576         reset(new DocumentStorage);
577         return const_cast<DocumentStorage&>(*storagePtr());
578     }
clonedStorage()579     DocumentStorage& clonedStorage() {
580         reset(storagePtr()->clone());
581         return const_cast<DocumentStorage&>(*storagePtr());
582     }
583 
584     // recursive helpers for same-named public methods
585     MutableValue getNestedFieldHelper(const FieldPath& dottedField, size_t level);
586     MutableValue getNestedFieldHelper(const std::vector<Position>& positions, size_t level);
587 
588     // this should only be called by storage methods and peek/freeze
storagePtr()589     const DocumentStorage* storagePtr() const {
590         dassert(!_storage || typeid(*_storage) == typeid(const DocumentStorage));
591         return static_cast<const DocumentStorage*>(_storage);
592     }
593 
594     // These are both const to prevent modifications bypassing storage() method.
595     // They always point to NULL or an object with dynamic type DocumentStorage.
596     const RefCountable* _storageHolder;  // Only used in constructors and destructor
597     const RefCountable*& _storage;  // references either above member or genericRCPtr in a Value
598 };
599 
600 /// This is the public iterator over a document
601 class FieldIterator {
602 public:
FieldIterator(const Document & doc)603     explicit FieldIterator(const Document& doc) : _doc(doc), _it(_doc.storage().iterator()) {}
604 
605     /// Ask if there are more fields to return.
more()606     bool more() const {
607         return !_it.atEnd();
608     }
609 
610     /// Get next item and advance iterator
next()611     Document::FieldPair next() {
612         verify(more());
613 
614         Document::FieldPair fp(_it->nameSD(), _it->val);
615         _it.advance();
616         return fp;
617     }
618 
619 private:
620     // We'll hang on to the original document to ensure we keep its storage alive
621     Document _doc;
622     DocumentStorageIterator _it;
623 };
624 
625 /// Macro to create Document literals. Syntax is the same as the BSON("name" << 123) macro.
626 #define DOC(fields) ((DocumentStream() << fields).done())
627 
628 /** Macro to create Array-typed Value literals.
629  *  Syntax is the same as the BSON_ARRAY(123 << "foo") macro.
630  */
631 #define DOC_ARRAY(fields) ((ValueArrayStream() << fields).done())
632 
633 
634 // These classes are only for the implementation of the DOC and DOC_ARRAY macros.
635 // They should not be used for any other reason.
636 class DocumentStream {
637     // The stream alternates between DocumentStream taking a fieldname
638     // and ValueStream taking a Value.
639     class ValueStream {
640     public:
ValueStream(DocumentStream & builder)641         ValueStream(DocumentStream& builder) : builder(builder) {}
642 
643         DocumentStream& operator<<(const Value& val) {
644             builder._md[name] = val;
645             return builder;
646         }
647 
648         /// support anything directly supported by a value constructor
649         template <typename T>
650         DocumentStream& operator<<(const T& val) {
651             return *this << Value(val);
652         }
653 
654         StringData name;
655         DocumentStream& builder;
656     };
657 
658 public:
DocumentStream()659     DocumentStream() : _stream(*this) {}
660 
661     ValueStream& operator<<(StringData name) {
662         _stream.name = name;
663         return _stream;
664     }
665 
done()666     Document done() {
667         return _md.freeze();
668     }
669 
670 private:
671     ValueStream _stream;
672     MutableDocument _md;
673 };
674 
675 class ValueArrayStream {
676 public:
677     ValueArrayStream& operator<<(const Value& val) {
678         _array.push_back(val);
679         return *this;
680     }
681 
682     /// support anything directly supported by a value constructor
683     template <typename T>
684     ValueArrayStream& operator<<(const T& val) {
685         return *this << Value(val);
686     }
687 
done()688     Value done() {
689         return Value(std::move(_array));
690     }
691 
692 private:
693     std::vector<Value> _array;
694 };
695 
swap(mongo::Document & lhs,mongo::Document & rhs)696 inline void swap(mongo::Document& lhs, mongo::Document& rhs) {
697     lhs.swap(rhs);
698 }
699 
700 /* ======================= INLINED IMPLEMENTATIONS ========================== */
701 
fieldIterator()702 inline FieldIterator Document::fieldIterator() const {
703     return FieldIterator(*this);
704 }
705 
getField(Position pos)706 inline MutableValue MutableValue::getField(Position pos) {
707     return MutableDocument(*this).getField(pos);
708 }
getField(StringData key)709 inline MutableValue MutableValue::getField(StringData key) {
710     return MutableDocument(*this).getField(key);
711 }
712 }
713