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 bson
8 9 import (
10 "bytes"
11 12 "go.mongodb.org/mongo-driver/bson/bsoncodec"
13 "go.mongodb.org/mongo-driver/bson/bsonrw"
14 "go.mongodb.org/mongo-driver/bson/bsontype"
15 )
16 17 // Unmarshaler is the interface implemented by types that can unmarshal a BSON
18 // document representation of themselves. The input can be assumed to be a valid
19 // encoding of a BSON document. UnmarshalBSON must copy the JSON data if it
20 // wishes to retain the data after returning.
21 //
22 // Unmarshaler is only used to unmarshal full BSON documents. To create custom
23 // BSON unmarshaling behavior for individual values in a BSON document,
24 // implement the ValueUnmarshaler interface instead.
25 type Unmarshaler interface {
26 UnmarshalBSON([]byte) error
27 }
28 29 // ValueUnmarshaler is the interface implemented by types that can unmarshal a
30 // BSON value representation of themselves. The input can be assumed to be a
31 // valid encoding of a BSON value. UnmarshalBSONValue must copy the BSON value
32 // bytes if it wishes to retain the data after returning.
33 //
34 // ValueUnmarshaler is only used to unmarshal individual values in a BSON
35 // document. To create custom BSON unmarshaling behavior for an entire BSON
36 // document, implement the Unmarshaler interface instead.
37 type ValueUnmarshaler interface {
38 UnmarshalBSONValue(bsontype.Type, []byte) error
39 }
40 41 // Unmarshal parses the BSON-encoded data and stores the result in the value
42 // pointed to by val. If val is nil or not a pointer, Unmarshal returns
43 // InvalidUnmarshalError.
44 func Unmarshal(data []byte, val interface{}) error {
45 return UnmarshalWithRegistry(DefaultRegistry, data, val)
46 }
47 48 // UnmarshalWithRegistry parses the BSON-encoded data using Registry r and
49 // stores the result in the value pointed to by val. If val is nil or not
50 // a pointer, UnmarshalWithRegistry returns InvalidUnmarshalError.
51 //
52 // Deprecated: Use [NewDecoder] and specify the Registry by calling [Decoder.SetRegistry] instead:
53 //
54 // dec, err := bson.NewDecoder(bsonrw.NewBSONDocumentReader(data))
55 // if err != nil {
56 // panic(err)
57 // }
58 // dec.SetRegistry(reg)
59 //
60 // See [Decoder] for more examples.
61 func UnmarshalWithRegistry(r *bsoncodec.Registry, data []byte, val interface{}) error {
62 vr := bsonrw.NewBSONDocumentReader(data)
63 return unmarshalFromReader(bsoncodec.DecodeContext{Registry: r}, vr, val)
64 }
65 66 // UnmarshalWithContext parses the BSON-encoded data using DecodeContext dc and
67 // stores the result in the value pointed to by val. If val is nil or not
68 // a pointer, UnmarshalWithRegistry returns InvalidUnmarshalError.
69 //
70 // Deprecated: Use [NewDecoder] and use the Decoder configuration methods to set the desired unmarshal
71 // behavior instead:
72 //
73 // dec, err := bson.NewDecoder(bsonrw.NewBSONDocumentReader(data))
74 // if err != nil {
75 // panic(err)
76 // }
77 // dec.DefaultDocumentM()
78 //
79 // See [Decoder] for more examples.
80 func UnmarshalWithContext(dc bsoncodec.DecodeContext, data []byte, val interface{}) error {
81 vr := bsonrw.NewBSONDocumentReader(data)
82 return unmarshalFromReader(dc, vr, val)
83 }
84 85 // UnmarshalValue parses the BSON value of type t with bson.DefaultRegistry and
86 // stores the result in the value pointed to by val. If val is nil or not a pointer,
87 // UnmarshalValue returns an error.
88 func UnmarshalValue(t bsontype.Type, data []byte, val interface{}) error {
89 return UnmarshalValueWithRegistry(DefaultRegistry, t, data, val)
90 }
91 92 // UnmarshalValueWithRegistry parses the BSON value of type t with registry r and
93 // stores the result in the value pointed to by val. If val is nil or not a pointer,
94 // UnmarshalValue returns an error.
95 //
96 // Deprecated: Using a custom registry to unmarshal individual BSON values will not be supported in
97 // Go Driver 2.0.
98 func UnmarshalValueWithRegistry(r *bsoncodec.Registry, t bsontype.Type, data []byte, val interface{}) error {
99 vr := bsonrw.NewBSONValueReader(t, data)
100 return unmarshalFromReader(bsoncodec.DecodeContext{Registry: r}, vr, val)
101 }
102 103 // UnmarshalExtJSON parses the extended JSON-encoded data and stores the result
104 // in the value pointed to by val. If val is nil or not a pointer, Unmarshal
105 // returns InvalidUnmarshalError.
106 func UnmarshalExtJSON(data []byte, canonical bool, val interface{}) error {
107 return UnmarshalExtJSONWithRegistry(DefaultRegistry, data, canonical, val)
108 }
109 110 // UnmarshalExtJSONWithRegistry parses the extended JSON-encoded data using
111 // Registry r and stores the result in the value pointed to by val. If val is
112 // nil or not a pointer, UnmarshalWithRegistry returns InvalidUnmarshalError.
113 //
114 // Deprecated: Use [NewDecoder] and specify the Registry by calling [Decoder.SetRegistry] instead:
115 //
116 // vr, err := bsonrw.NewExtJSONValueReader(bytes.NewReader(data), true)
117 // if err != nil {
118 // panic(err)
119 // }
120 // dec, err := bson.NewDecoder(vr)
121 // if err != nil {
122 // panic(err)
123 // }
124 // dec.SetRegistry(reg)
125 //
126 // See [Decoder] for more examples.
127 func UnmarshalExtJSONWithRegistry(r *bsoncodec.Registry, data []byte, canonical bool, val interface{}) error {
128 ejvr, err := bsonrw.NewExtJSONValueReader(bytes.NewReader(data), canonical)
129 if err != nil {
130 return err
131 }
132 133 return unmarshalFromReader(bsoncodec.DecodeContext{Registry: r}, ejvr, val)
134 }
135 136 // UnmarshalExtJSONWithContext parses the extended JSON-encoded data using
137 // DecodeContext dc and stores the result in the value pointed to by val. If val is
138 // nil or not a pointer, UnmarshalWithRegistry returns InvalidUnmarshalError.
139 //
140 // Deprecated: Use [NewDecoder] and use the Decoder configuration methods to set the desired unmarshal
141 // behavior instead:
142 //
143 // vr, err := bsonrw.NewExtJSONValueReader(bytes.NewReader(data), true)
144 // if err != nil {
145 // panic(err)
146 // }
147 // dec, err := bson.NewDecoder(vr)
148 // if err != nil {
149 // panic(err)
150 // }
151 // dec.DefaultDocumentM()
152 //
153 // See [Decoder] for more examples.
154 func UnmarshalExtJSONWithContext(dc bsoncodec.DecodeContext, data []byte, canonical bool, val interface{}) error {
155 ejvr, err := bsonrw.NewExtJSONValueReader(bytes.NewReader(data), canonical)
156 if err != nil {
157 return err
158 }
159 160 return unmarshalFromReader(dc, ejvr, val)
161 }
162 163 func unmarshalFromReader(dc bsoncodec.DecodeContext, vr bsonrw.ValueReader, val interface{}) error {
164 dec := decPool.Get().(*Decoder)
165 defer decPool.Put(dec)
166 167 err := dec.Reset(vr)
168 if err != nil {
169 return err
170 }
171 err = dec.SetContext(dc)
172 if err != nil {
173 return err
174 }
175 176 return dec.Decode(val)
177 }
178