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 bsoncodec // import "go.mongodb.org/mongo-driver/bson/bsoncodec"
8 9 import (
10 "fmt"
11 "reflect"
12 "strings"
13 14 "go.mongodb.org/mongo-driver/bson/bsonrw"
15 "go.mongodb.org/mongo-driver/bson/bsontype"
16 "go.mongodb.org/mongo-driver/bson/primitive"
17 )
18 19 var (
20 emptyValue = reflect.Value{}
21 )
22 23 // Marshaler is an interface implemented by types that can marshal themselves
24 // into a BSON document represented as bytes. The bytes returned must be a valid
25 // BSON document if the error is nil.
26 //
27 // Deprecated: Use [go.mongodb.org/mongo-driver/bson.Marshaler] instead.
28 type Marshaler interface {
29 MarshalBSON() ([]byte, error)
30 }
31 32 // ValueMarshaler is an interface implemented by types that can marshal
33 // themselves into a BSON value as bytes. The type must be the valid type for
34 // the bytes returned. The bytes and byte type together must be valid if the
35 // error is nil.
36 //
37 // Deprecated: Use [go.mongodb.org/mongo-driver/bson.ValueMarshaler] instead.
38 type ValueMarshaler interface {
39 MarshalBSONValue() (bsontype.Type, []byte, error)
40 }
41 42 // Unmarshaler is an interface implemented by types that can unmarshal a BSON
43 // document representation of themselves. The BSON bytes can be assumed to be
44 // valid. UnmarshalBSON must copy the BSON bytes if it wishes to retain the data
45 // after returning.
46 //
47 // Deprecated: Use [go.mongodb.org/mongo-driver/bson.Unmarshaler] instead.
48 type Unmarshaler interface {
49 UnmarshalBSON([]byte) error
50 }
51 52 // ValueUnmarshaler is an interface implemented by types that can unmarshal a
53 // BSON value representation of themselves. The BSON bytes and type can be
54 // assumed to be valid. UnmarshalBSONValue must copy the BSON value bytes if it
55 // wishes to retain the data after returning.
56 //
57 // Deprecated: Use [go.mongodb.org/mongo-driver/bson.ValueUnmarshaler] instead.
58 type ValueUnmarshaler interface {
59 UnmarshalBSONValue(bsontype.Type, []byte) error
60 }
61 62 // ValueEncoderError is an error returned from a ValueEncoder when the provided value can't be
63 // encoded by the ValueEncoder.
64 type ValueEncoderError struct {
65 Name string
66 Types []reflect.Type
67 Kinds []reflect.Kind
68 Received reflect.Value
69 }
70 71 func (vee ValueEncoderError) Error() string {
72 typeKinds := make([]string, 0, len(vee.Types)+len(vee.Kinds))
73 for _, t := range vee.Types {
74 typeKinds = append(typeKinds, t.String())
75 }
76 for _, k := range vee.Kinds {
77 if k == reflect.Map {
78 typeKinds = append(typeKinds, "map[string]*")
79 continue
80 }
81 typeKinds = append(typeKinds, k.String())
82 }
83 received := vee.Received.Kind().String()
84 if vee.Received.IsValid() {
85 received = vee.Received.Type().String()
86 }
87 return fmt.Sprintf("%s can only encode valid %s, but got %s", vee.Name, strings.Join(typeKinds, ", "), received)
88 }
89 90 // ValueDecoderError is an error returned from a ValueDecoder when the provided value can't be
91 // decoded by the ValueDecoder.
92 type ValueDecoderError struct {
93 Name string
94 Types []reflect.Type
95 Kinds []reflect.Kind
96 Received reflect.Value
97 }
98 99 func (vde ValueDecoderError) Error() string {
100 typeKinds := make([]string, 0, len(vde.Types)+len(vde.Kinds))
101 for _, t := range vde.Types {
102 typeKinds = append(typeKinds, t.String())
103 }
104 for _, k := range vde.Kinds {
105 if k == reflect.Map {
106 typeKinds = append(typeKinds, "map[string]*")
107 continue
108 }
109 typeKinds = append(typeKinds, k.String())
110 }
111 received := vde.Received.Kind().String()
112 if vde.Received.IsValid() {
113 received = vde.Received.Type().String()
114 }
115 return fmt.Sprintf("%s can only decode valid and settable %s, but got %s", vde.Name, strings.Join(typeKinds, ", "), received)
116 }
117 118 // EncodeContext is the contextual information required for a Codec to encode a
119 // value.
120 type EncodeContext struct {
121 *Registry
122 123 // MinSize causes the Encoder to marshal Go integer values (int, int8, int16, int32, int64,
124 // uint, uint8, uint16, uint32, or uint64) as the minimum BSON int size (either 32 or 64 bits)
125 // that can represent the integer value.
126 //
127 // Deprecated: Use bson.Encoder.IntMinSize instead.
128 MinSize bool
129 130 errorOnInlineDuplicates bool
131 stringifyMapKeysWithFmt bool
132 nilMapAsEmpty bool
133 nilSliceAsEmpty bool
134 nilByteSliceAsEmpty bool
135 omitZeroStruct bool
136 useJSONStructTags bool
137 }
138 139 // ErrorOnInlineDuplicates causes the Encoder to return an error if there is a duplicate field in
140 // the marshaled BSON when the "inline" struct tag option is set.
141 //
142 // Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.ErrorOnInlineDuplicates] instead.
143 func (ec *EncodeContext) ErrorOnInlineDuplicates() {
144 ec.errorOnInlineDuplicates = true
145 }
146 147 // StringifyMapKeysWithFmt causes the Encoder to convert Go map keys to BSON document field name
148 // strings using fmt.Sprintf() instead of the default string conversion logic.
149 //
150 // Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.StringifyMapKeysWithFmt] instead.
151 func (ec *EncodeContext) StringifyMapKeysWithFmt() {
152 ec.stringifyMapKeysWithFmt = true
153 }
154 155 // NilMapAsEmpty causes the Encoder to marshal nil Go maps as empty BSON documents instead of BSON
156 // null.
157 //
158 // Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.NilMapAsEmpty] instead.
159 func (ec *EncodeContext) NilMapAsEmpty() {
160 ec.nilMapAsEmpty = true
161 }
162 163 // NilSliceAsEmpty causes the Encoder to marshal nil Go slices as empty BSON arrays instead of BSON
164 // null.
165 //
166 // Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.NilSliceAsEmpty] instead.
167 func (ec *EncodeContext) NilSliceAsEmpty() {
168 ec.nilSliceAsEmpty = true
169 }
170 171 // NilByteSliceAsEmpty causes the Encoder to marshal nil Go byte slices as empty BSON binary values
172 // instead of BSON null.
173 //
174 // Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.NilByteSliceAsEmpty] instead.
175 func (ec *EncodeContext) NilByteSliceAsEmpty() {
176 ec.nilByteSliceAsEmpty = true
177 }
178 179 // OmitZeroStruct causes the Encoder to consider the zero value for a struct (e.g. MyStruct{})
180 // as empty and omit it from the marshaled BSON when the "omitempty" struct tag option is set.
181 //
182 // Note that the Encoder only examines exported struct fields when determining if a struct is the
183 // zero value. It considers pointers to a zero struct value (e.g. &MyStruct{}) not empty.
184 //
185 // Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.OmitZeroStruct] instead.
186 func (ec *EncodeContext) OmitZeroStruct() {
187 ec.omitZeroStruct = true
188 }
189 190 // UseJSONStructTags causes the Encoder to fall back to using the "json" struct tag if a "bson"
191 // struct tag is not specified.
192 //
193 // Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.UseJSONStructTags] instead.
194 func (ec *EncodeContext) UseJSONStructTags() {
195 ec.useJSONStructTags = true
196 }
197 198 // DecodeContext is the contextual information required for a Codec to decode a
199 // value.
200 type DecodeContext struct {
201 *Registry
202 203 // Truncate, if true, instructs decoders to to truncate the fractional part of BSON "double"
204 // values when attempting to unmarshal them into a Go integer (int, int8, int16, int32, int64,
205 // uint, uint8, uint16, uint32, or uint64) struct field. The truncation logic does not apply to
206 // BSON "decimal128" values.
207 //
208 // Deprecated: Use bson.Decoder.AllowTruncatingDoubles instead.
209 Truncate bool
210 211 // Ancestor is the type of a containing document. This is mainly used to determine what type
212 // should be used when decoding an embedded document into an empty interface. For example, if
213 // Ancestor is a bson.M, BSON embedded document values being decoded into an empty interface
214 // will be decoded into a bson.M.
215 //
216 // Deprecated: Use bson.Decoder.DefaultDocumentM or bson.Decoder.DefaultDocumentD instead.
217 Ancestor reflect.Type
218 219 // defaultDocumentType specifies the Go type to decode top-level and nested BSON documents into. In particular, the
220 // usage for this field is restricted to data typed as "interface{}" or "map[string]interface{}". If DocumentType is
221 // set to a type that a BSON document cannot be unmarshaled into (e.g. "string"), unmarshalling will result in an
222 // error. DocumentType overrides the Ancestor field.
223 defaultDocumentType reflect.Type
224 225 binaryAsSlice bool
226 useJSONStructTags bool
227 useLocalTimeZone bool
228 zeroMaps bool
229 zeroStructs bool
230 }
231 232 // BinaryAsSlice causes the Decoder to unmarshal BSON binary field values that are the "Generic" or
233 // "Old" BSON binary subtype as a Go byte slice instead of a primitive.Binary.
234 //
235 // Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.BinaryAsSlice] instead.
236 func (dc *DecodeContext) BinaryAsSlice() {
237 dc.binaryAsSlice = true
238 }
239 240 // UseJSONStructTags causes the Decoder to fall back to using the "json" struct tag if a "bson"
241 // struct tag is not specified.
242 //
243 // Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.UseJSONStructTags] instead.
244 func (dc *DecodeContext) UseJSONStructTags() {
245 dc.useJSONStructTags = true
246 }
247 248 // UseLocalTimeZone causes the Decoder to unmarshal time.Time values in the local timezone instead
249 // of the UTC timezone.
250 //
251 // Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.UseLocalTimeZone] instead.
252 func (dc *DecodeContext) UseLocalTimeZone() {
253 dc.useLocalTimeZone = true
254 }
255 256 // ZeroMaps causes the Decoder to delete any existing values from Go maps in the destination value
257 // passed to Decode before unmarshaling BSON documents into them.
258 //
259 // Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.ZeroMaps] instead.
260 func (dc *DecodeContext) ZeroMaps() {
261 dc.zeroMaps = true
262 }
263 264 // ZeroStructs causes the Decoder to delete any existing values from Go structs in the destination
265 // value passed to Decode before unmarshaling BSON documents into them.
266 //
267 // Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.ZeroStructs] instead.
268 func (dc *DecodeContext) ZeroStructs() {
269 dc.zeroStructs = true
270 }
271 272 // DefaultDocumentM causes the Decoder to always unmarshal documents into the primitive.M type. This
273 // behavior is restricted to data typed as "interface{}" or "map[string]interface{}".
274 //
275 // Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.DefaultDocumentM] instead.
276 func (dc *DecodeContext) DefaultDocumentM() {
277 dc.defaultDocumentType = reflect.TypeOf(primitive.M{})
278 }
279 280 // DefaultDocumentD causes the Decoder to always unmarshal documents into the primitive.D type. This
281 // behavior is restricted to data typed as "interface{}" or "map[string]interface{}".
282 //
283 // Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.DefaultDocumentD] instead.
284 func (dc *DecodeContext) DefaultDocumentD() {
285 dc.defaultDocumentType = reflect.TypeOf(primitive.D{})
286 }
287 288 // ValueCodec is an interface for encoding and decoding a reflect.Value.
289 // values.
290 //
291 // Deprecated: Use [ValueEncoder] and [ValueDecoder] instead.
292 type ValueCodec interface {
293 ValueEncoder
294 ValueDecoder
295 }
296 297 // ValueEncoder is the interface implemented by types that can handle the encoding of a value.
298 type ValueEncoder interface {
299 EncodeValue(EncodeContext, bsonrw.ValueWriter, reflect.Value) error
300 }
301 302 // ValueEncoderFunc is an adapter function that allows a function with the correct signature to be
303 // used as a ValueEncoder.
304 type ValueEncoderFunc func(EncodeContext, bsonrw.ValueWriter, reflect.Value) error
305 306 // EncodeValue implements the ValueEncoder interface.
307 func (fn ValueEncoderFunc) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
308 return fn(ec, vw, val)
309 }
310 311 // ValueDecoder is the interface implemented by types that can handle the decoding of a value.
312 type ValueDecoder interface {
313 DecodeValue(DecodeContext, bsonrw.ValueReader, reflect.Value) error
314 }
315 316 // ValueDecoderFunc is an adapter function that allows a function with the correct signature to be
317 // used as a ValueDecoder.
318 type ValueDecoderFunc func(DecodeContext, bsonrw.ValueReader, reflect.Value) error
319 320 // DecodeValue implements the ValueDecoder interface.
321 func (fn ValueDecoderFunc) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
322 return fn(dc, vr, val)
323 }
324 325 // typeDecoder is the interface implemented by types that can handle the decoding of a value given its type.
326 type typeDecoder interface {
327 decodeType(DecodeContext, bsonrw.ValueReader, reflect.Type) (reflect.Value, error)
328 }
329 330 // typeDecoderFunc is an adapter function that allows a function with the correct signature to be used as a typeDecoder.
331 type typeDecoderFunc func(DecodeContext, bsonrw.ValueReader, reflect.Type) (reflect.Value, error)
332 333 func (fn typeDecoderFunc) decodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
334 return fn(dc, vr, t)
335 }
336 337 // decodeAdapter allows two functions with the correct signatures to be used as both a ValueDecoder and typeDecoder.
338 type decodeAdapter struct {
339 ValueDecoderFunc
340 typeDecoderFunc
341 }
342 343 var _ ValueDecoder = decodeAdapter{}
344 var _ typeDecoder = decodeAdapter{}
345 346 // decodeTypeOrValue calls decoder.decodeType is decoder is a typeDecoder. Otherwise, it allocates a new element of type
347 // t and calls decoder.DecodeValue on it.
348 func decodeTypeOrValue(decoder ValueDecoder, dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
349 td, _ := decoder.(typeDecoder)
350 return decodeTypeOrValueWithInfo(decoder, td, dc, vr, t, true)
351 }
352 353 func decodeTypeOrValueWithInfo(vd ValueDecoder, td typeDecoder, dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type, convert bool) (reflect.Value, error) {
354 if td != nil {
355 val, err := td.decodeType(dc, vr, t)
356 if err == nil && convert && val.Type() != t {
357 // This conversion step is necessary for slices and maps. If a user declares variables like:
358 //
359 // type myBool bool
360 // var m map[string]myBool
361 //
362 // and tries to decode BSON bytes into the map, the decoding will fail if this conversion is not present
363 // because we'll try to assign a value of type bool to one of type myBool.
364 val = val.Convert(t)
365 }
366 return val, err
367 }
368 369 val := reflect.New(t).Elem()
370 err := vd.DecodeValue(dc, vr, val)
371 return val, err
372 }
373 374 // CodecZeroer is the interface implemented by Codecs that can also determine if
375 // a value of the type that would be encoded is zero.
376 //
377 // Deprecated: Defining custom rules for the zero/empty value will not be supported in Go Driver
378 // 2.0. Users who want to omit empty complex values should use a pointer field and set the value to
379 // nil instead.
380 type CodecZeroer interface {
381 IsTypeZero(interface{}) bool
382 }
383