mirror of
https://github.com/go-gitea/gitea
synced 2025-07-22 18:28:37 +00:00
Use vendored go-swagger (#8087)
* Use vendored go-swagger * vendor go-swagger * revert un wanteed change * remove un-needed GO111MODULE * Update Makefile Co-Authored-By: techknowlogick <matti@mdranta.net>
This commit is contained in:
committed by
Lauris BH
parent
4cb1bdddc8
commit
9fe4437bda
163
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/bsoncodec.go
generated
vendored
Normal file
163
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/bsoncodec.go
generated
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
// Copyright (C) MongoDB, Inc. 2017-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package bsoncodec // import "go.mongodb.org/mongo-driver/bson/bsoncodec"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/bsonrw"
|
||||
"go.mongodb.org/mongo-driver/bson/bsontype"
|
||||
)
|
||||
|
||||
// Marshaler is an interface implemented by types that can marshal themselves
|
||||
// into a BSON document represented as bytes. The bytes returned must be a valid
|
||||
// BSON document if the error is nil.
|
||||
type Marshaler interface {
|
||||
MarshalBSON() ([]byte, error)
|
||||
}
|
||||
|
||||
// ValueMarshaler is an interface implemented by types that can marshal
|
||||
// themselves into a BSON value as bytes. The type must be the valid type for
|
||||
// the bytes returned. The bytes and byte type together must be valid if the
|
||||
// error is nil.
|
||||
type ValueMarshaler interface {
|
||||
MarshalBSONValue() (bsontype.Type, []byte, error)
|
||||
}
|
||||
|
||||
// Unmarshaler is an interface implemented by types that can unmarshal a BSON
|
||||
// document representation of themselves. The BSON bytes can be assumed to be
|
||||
// valid. UnmarshalBSON must copy the BSON bytes if it wishes to retain the data
|
||||
// after returning.
|
||||
type Unmarshaler interface {
|
||||
UnmarshalBSON([]byte) error
|
||||
}
|
||||
|
||||
// ValueUnmarshaler is an interface implemented by types that can unmarshal a
|
||||
// BSON value representaiton of themselves. The BSON bytes and type can be
|
||||
// assumed to be valid. UnmarshalBSONValue must copy the BSON value bytes if it
|
||||
// wishes to retain the data after returning.
|
||||
type ValueUnmarshaler interface {
|
||||
UnmarshalBSONValue(bsontype.Type, []byte) error
|
||||
}
|
||||
|
||||
// ValueEncoderError is an error returned from a ValueEncoder when the provided value can't be
|
||||
// encoded by the ValueEncoder.
|
||||
type ValueEncoderError struct {
|
||||
Name string
|
||||
Types []reflect.Type
|
||||
Kinds []reflect.Kind
|
||||
Received reflect.Value
|
||||
}
|
||||
|
||||
func (vee ValueEncoderError) Error() string {
|
||||
typeKinds := make([]string, 0, len(vee.Types)+len(vee.Kinds))
|
||||
for _, t := range vee.Types {
|
||||
typeKinds = append(typeKinds, t.String())
|
||||
}
|
||||
for _, k := range vee.Kinds {
|
||||
if k == reflect.Map {
|
||||
typeKinds = append(typeKinds, "map[string]*")
|
||||
continue
|
||||
}
|
||||
typeKinds = append(typeKinds, k.String())
|
||||
}
|
||||
received := vee.Received.Kind().String()
|
||||
if vee.Received.IsValid() {
|
||||
received = vee.Received.Type().String()
|
||||
}
|
||||
return fmt.Sprintf("%s can only encode valid %s, but got %s", vee.Name, strings.Join(typeKinds, ", "), received)
|
||||
}
|
||||
|
||||
// ValueDecoderError is an error returned from a ValueDecoder when the provided value can't be
|
||||
// decoded by the ValueDecoder.
|
||||
type ValueDecoderError struct {
|
||||
Name string
|
||||
Types []reflect.Type
|
||||
Kinds []reflect.Kind
|
||||
Received reflect.Value
|
||||
}
|
||||
|
||||
func (vde ValueDecoderError) Error() string {
|
||||
typeKinds := make([]string, 0, len(vde.Types)+len(vde.Kinds))
|
||||
for _, t := range vde.Types {
|
||||
typeKinds = append(typeKinds, t.String())
|
||||
}
|
||||
for _, k := range vde.Kinds {
|
||||
if k == reflect.Map {
|
||||
typeKinds = append(typeKinds, "map[string]*")
|
||||
continue
|
||||
}
|
||||
typeKinds = append(typeKinds, k.String())
|
||||
}
|
||||
received := vde.Received.Kind().String()
|
||||
if vde.Received.IsValid() {
|
||||
received = vde.Received.Type().String()
|
||||
}
|
||||
return fmt.Sprintf("%s can only decode valid and settable %s, but got %s", vde.Name, strings.Join(typeKinds, ", "), received)
|
||||
}
|
||||
|
||||
// EncodeContext is the contextual information required for a Codec to encode a
|
||||
// value.
|
||||
type EncodeContext struct {
|
||||
*Registry
|
||||
MinSize bool
|
||||
}
|
||||
|
||||
// DecodeContext is the contextual information required for a Codec to decode a
|
||||
// value.
|
||||
type DecodeContext struct {
|
||||
*Registry
|
||||
Truncate bool
|
||||
// Ancestor is the type of a containing document. This is mainly used to determine what type
|
||||
// should be used when decoding an embedded document into an empty interface. For example, if
|
||||
// Ancestor is a bson.M, BSON embedded document values being decoded into an empty interface
|
||||
// will be decoded into a bson.M.
|
||||
Ancestor reflect.Type
|
||||
}
|
||||
|
||||
// ValueCodec is the interface that groups the methods to encode and decode
|
||||
// values.
|
||||
type ValueCodec interface {
|
||||
ValueEncoder
|
||||
ValueDecoder
|
||||
}
|
||||
|
||||
// ValueEncoder is the interface implemented by types that can handle the encoding of a value.
|
||||
type ValueEncoder interface {
|
||||
EncodeValue(EncodeContext, bsonrw.ValueWriter, reflect.Value) error
|
||||
}
|
||||
|
||||
// ValueEncoderFunc is an adapter function that allows a function with the correct signature to be
|
||||
// used as a ValueEncoder.
|
||||
type ValueEncoderFunc func(EncodeContext, bsonrw.ValueWriter, reflect.Value) error
|
||||
|
||||
// EncodeValue implements the ValueEncoder interface.
|
||||
func (fn ValueEncoderFunc) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
return fn(ec, vw, val)
|
||||
}
|
||||
|
||||
// ValueDecoder is the interface implemented by types that can handle the decoding of a value.
|
||||
type ValueDecoder interface {
|
||||
DecodeValue(DecodeContext, bsonrw.ValueReader, reflect.Value) error
|
||||
}
|
||||
|
||||
// ValueDecoderFunc is an adapter function that allows a function with the correct signature to be
|
||||
// used as a ValueDecoder.
|
||||
type ValueDecoderFunc func(DecodeContext, bsonrw.ValueReader, reflect.Value) error
|
||||
|
||||
// DecodeValue implements the ValueDecoder interface.
|
||||
func (fn ValueDecoderFunc) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
return fn(dc, vr, val)
|
||||
}
|
||||
|
||||
// CodecZeroer is the interface implemented by Codecs that can also determine if
|
||||
// a value of the type that would be encoded is zero.
|
||||
type CodecZeroer interface {
|
||||
IsTypeZero(interface{}) bool
|
||||
}
|
1014
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_decoders.go
generated
vendored
Normal file
1014
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_decoders.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
648
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_encoders.go
generated
vendored
Normal file
648
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_encoders.go
generated
vendored
Normal file
@@ -0,0 +1,648 @@
|
||||
// Copyright (C) MongoDB, Inc. 2017-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package bsoncodec
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/bsonrw"
|
||||
"go.mongodb.org/mongo-driver/bson/bsontype"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
|
||||
)
|
||||
|
||||
var defaultValueEncoders DefaultValueEncoders
|
||||
|
||||
var bvwPool = bsonrw.NewBSONValueWriterPool()
|
||||
|
||||
var sliceWriterPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
sw := make(bsonrw.SliceWriter, 0, 0)
|
||||
return &sw
|
||||
},
|
||||
}
|
||||
|
||||
func encodeElement(ec EncodeContext, dw bsonrw.DocumentWriter, e primitive.E) error {
|
||||
vw, err := dw.WriteDocumentElement(e.Key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if e.Value == nil {
|
||||
return vw.WriteNull()
|
||||
}
|
||||
encoder, err := ec.LookupEncoder(reflect.TypeOf(e.Value))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = encoder.EncodeValue(ec, vw, reflect.ValueOf(e.Value))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DefaultValueEncoders is a namespace type for the default ValueEncoders used
|
||||
// when creating a registry.
|
||||
type DefaultValueEncoders struct{}
|
||||
|
||||
// RegisterDefaultEncoders will register the encoder methods attached to DefaultValueEncoders with
|
||||
// the provided RegistryBuilder.
|
||||
func (dve DefaultValueEncoders) RegisterDefaultEncoders(rb *RegistryBuilder) {
|
||||
if rb == nil {
|
||||
panic(errors.New("argument to RegisterDefaultEncoders must not be nil"))
|
||||
}
|
||||
rb.
|
||||
RegisterEncoder(tByteSlice, ValueEncoderFunc(dve.ByteSliceEncodeValue)).
|
||||
RegisterEncoder(tTime, ValueEncoderFunc(dve.TimeEncodeValue)).
|
||||
RegisterEncoder(tEmpty, ValueEncoderFunc(dve.EmptyInterfaceEncodeValue)).
|
||||
RegisterEncoder(tOID, ValueEncoderFunc(dve.ObjectIDEncodeValue)).
|
||||
RegisterEncoder(tDecimal, ValueEncoderFunc(dve.Decimal128EncodeValue)).
|
||||
RegisterEncoder(tJSONNumber, ValueEncoderFunc(dve.JSONNumberEncodeValue)).
|
||||
RegisterEncoder(tURL, ValueEncoderFunc(dve.URLEncodeValue)).
|
||||
RegisterEncoder(tValueMarshaler, ValueEncoderFunc(dve.ValueMarshalerEncodeValue)).
|
||||
RegisterEncoder(tMarshaler, ValueEncoderFunc(dve.MarshalerEncodeValue)).
|
||||
RegisterEncoder(tProxy, ValueEncoderFunc(dve.ProxyEncodeValue)).
|
||||
RegisterEncoder(tJavaScript, ValueEncoderFunc(dve.JavaScriptEncodeValue)).
|
||||
RegisterEncoder(tSymbol, ValueEncoderFunc(dve.SymbolEncodeValue)).
|
||||
RegisterEncoder(tBinary, ValueEncoderFunc(dve.BinaryEncodeValue)).
|
||||
RegisterEncoder(tUndefined, ValueEncoderFunc(dve.UndefinedEncodeValue)).
|
||||
RegisterEncoder(tDateTime, ValueEncoderFunc(dve.DateTimeEncodeValue)).
|
||||
RegisterEncoder(tNull, ValueEncoderFunc(dve.NullEncodeValue)).
|
||||
RegisterEncoder(tRegex, ValueEncoderFunc(dve.RegexEncodeValue)).
|
||||
RegisterEncoder(tDBPointer, ValueEncoderFunc(dve.DBPointerEncodeValue)).
|
||||
RegisterEncoder(tTimestamp, ValueEncoderFunc(dve.TimestampEncodeValue)).
|
||||
RegisterEncoder(tMinKey, ValueEncoderFunc(dve.MinKeyEncodeValue)).
|
||||
RegisterEncoder(tMaxKey, ValueEncoderFunc(dve.MaxKeyEncodeValue)).
|
||||
RegisterEncoder(tCoreDocument, ValueEncoderFunc(dve.CoreDocumentEncodeValue)).
|
||||
RegisterEncoder(tCodeWithScope, ValueEncoderFunc(dve.CodeWithScopeEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Bool, ValueEncoderFunc(dve.BooleanEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Int, ValueEncoderFunc(dve.IntEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Int8, ValueEncoderFunc(dve.IntEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Int16, ValueEncoderFunc(dve.IntEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Int32, ValueEncoderFunc(dve.IntEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Int64, ValueEncoderFunc(dve.IntEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Uint, ValueEncoderFunc(dve.UintEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Uint8, ValueEncoderFunc(dve.UintEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Uint16, ValueEncoderFunc(dve.UintEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Uint32, ValueEncoderFunc(dve.UintEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Uint64, ValueEncoderFunc(dve.UintEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Float32, ValueEncoderFunc(dve.FloatEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Float64, ValueEncoderFunc(dve.FloatEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Array, ValueEncoderFunc(dve.ArrayEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Map, ValueEncoderFunc(dve.MapEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Slice, ValueEncoderFunc(dve.SliceEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.String, ValueEncoderFunc(dve.StringEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Struct, &StructCodec{cache: make(map[reflect.Type]*structDescription), parser: DefaultStructTagParser}).
|
||||
RegisterDefaultEncoder(reflect.Ptr, NewPointerCodec())
|
||||
}
|
||||
|
||||
// BooleanEncodeValue is the ValueEncoderFunc for bool types.
|
||||
func (dve DefaultValueEncoders) BooleanEncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Kind() != reflect.Bool {
|
||||
return ValueEncoderError{Name: "BooleanEncodeValue", Kinds: []reflect.Kind{reflect.Bool}, Received: val}
|
||||
}
|
||||
return vw.WriteBoolean(val.Bool())
|
||||
}
|
||||
|
||||
func fitsIn32Bits(i int64) bool {
|
||||
return math.MinInt32 <= i && i <= math.MaxInt32
|
||||
}
|
||||
|
||||
// IntEncodeValue is the ValueEncoderFunc for int types.
|
||||
func (dve DefaultValueEncoders) IntEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
switch val.Kind() {
|
||||
case reflect.Int8, reflect.Int16, reflect.Int32:
|
||||
return vw.WriteInt32(int32(val.Int()))
|
||||
case reflect.Int:
|
||||
i64 := val.Int()
|
||||
if fitsIn32Bits(i64) {
|
||||
return vw.WriteInt32(int32(i64))
|
||||
}
|
||||
return vw.WriteInt64(i64)
|
||||
case reflect.Int64:
|
||||
i64 := val.Int()
|
||||
if ec.MinSize && fitsIn32Bits(i64) {
|
||||
return vw.WriteInt32(int32(i64))
|
||||
}
|
||||
return vw.WriteInt64(i64)
|
||||
}
|
||||
|
||||
return ValueEncoderError{
|
||||
Name: "IntEncodeValue",
|
||||
Kinds: []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int},
|
||||
Received: val,
|
||||
}
|
||||
}
|
||||
|
||||
// UintEncodeValue is the ValueEncoderFunc for uint types.
|
||||
func (dve DefaultValueEncoders) UintEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
switch val.Kind() {
|
||||
case reflect.Uint8, reflect.Uint16:
|
||||
return vw.WriteInt32(int32(val.Uint()))
|
||||
case reflect.Uint, reflect.Uint32, reflect.Uint64:
|
||||
u64 := val.Uint()
|
||||
if ec.MinSize && u64 <= math.MaxInt32 {
|
||||
return vw.WriteInt32(int32(u64))
|
||||
}
|
||||
if u64 > math.MaxInt64 {
|
||||
return fmt.Errorf("%d overflows int64", u64)
|
||||
}
|
||||
return vw.WriteInt64(int64(u64))
|
||||
}
|
||||
|
||||
return ValueEncoderError{
|
||||
Name: "UintEncodeValue",
|
||||
Kinds: []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint},
|
||||
Received: val,
|
||||
}
|
||||
}
|
||||
|
||||
// FloatEncodeValue is the ValueEncoderFunc for float types.
|
||||
func (dve DefaultValueEncoders) FloatEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
switch val.Kind() {
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return vw.WriteDouble(val.Float())
|
||||
}
|
||||
|
||||
return ValueEncoderError{Name: "FloatEncodeValue", Kinds: []reflect.Kind{reflect.Float32, reflect.Float64}, Received: val}
|
||||
}
|
||||
|
||||
// StringEncodeValue is the ValueEncoderFunc for string types.
|
||||
func (dve DefaultValueEncoders) StringEncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if val.Kind() != reflect.String {
|
||||
return ValueEncoderError{
|
||||
Name: "StringEncodeValue",
|
||||
Kinds: []reflect.Kind{reflect.String},
|
||||
Received: val,
|
||||
}
|
||||
}
|
||||
|
||||
return vw.WriteString(val.String())
|
||||
}
|
||||
|
||||
// ObjectIDEncodeValue is the ValueEncoderFunc for primitive.ObjectID.
|
||||
func (dve DefaultValueEncoders) ObjectIDEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tOID {
|
||||
return ValueEncoderError{Name: "ObjectIDEncodeValue", Types: []reflect.Type{tOID}, Received: val}
|
||||
}
|
||||
return vw.WriteObjectID(val.Interface().(primitive.ObjectID))
|
||||
}
|
||||
|
||||
// Decimal128EncodeValue is the ValueEncoderFunc for primitive.Decimal128.
|
||||
func (dve DefaultValueEncoders) Decimal128EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tDecimal {
|
||||
return ValueEncoderError{Name: "Decimal128EncodeValue", Types: []reflect.Type{tDecimal}, Received: val}
|
||||
}
|
||||
return vw.WriteDecimal128(val.Interface().(primitive.Decimal128))
|
||||
}
|
||||
|
||||
// JSONNumberEncodeValue is the ValueEncoderFunc for json.Number.
|
||||
func (dve DefaultValueEncoders) JSONNumberEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tJSONNumber {
|
||||
return ValueEncoderError{Name: "JSONNumberEncodeValue", Types: []reflect.Type{tJSONNumber}, Received: val}
|
||||
}
|
||||
jsnum := val.Interface().(json.Number)
|
||||
|
||||
// Attempt int first, then float64
|
||||
if i64, err := jsnum.Int64(); err == nil {
|
||||
return dve.IntEncodeValue(ec, vw, reflect.ValueOf(i64))
|
||||
}
|
||||
|
||||
f64, err := jsnum.Float64()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return dve.FloatEncodeValue(ec, vw, reflect.ValueOf(f64))
|
||||
}
|
||||
|
||||
// URLEncodeValue is the ValueEncoderFunc for url.URL.
|
||||
func (dve DefaultValueEncoders) URLEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tURL {
|
||||
return ValueEncoderError{Name: "URLEncodeValue", Types: []reflect.Type{tURL}, Received: val}
|
||||
}
|
||||
u := val.Interface().(url.URL)
|
||||
return vw.WriteString(u.String())
|
||||
}
|
||||
|
||||
// TimeEncodeValue is the ValueEncoderFunc for time.TIme.
|
||||
func (dve DefaultValueEncoders) TimeEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tTime {
|
||||
return ValueEncoderError{Name: "TimeEncodeValue", Types: []reflect.Type{tTime}, Received: val}
|
||||
}
|
||||
tt := val.Interface().(time.Time)
|
||||
return vw.WriteDateTime(tt.Unix()*1000 + int64(tt.Nanosecond()/1e6))
|
||||
}
|
||||
|
||||
// ByteSliceEncodeValue is the ValueEncoderFunc for []byte.
|
||||
func (dve DefaultValueEncoders) ByteSliceEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tByteSlice {
|
||||
return ValueEncoderError{Name: "ByteSliceEncodeValue", Types: []reflect.Type{tByteSlice}, Received: val}
|
||||
}
|
||||
if val.IsNil() {
|
||||
return vw.WriteNull()
|
||||
}
|
||||
return vw.WriteBinary(val.Interface().([]byte))
|
||||
}
|
||||
|
||||
// MapEncodeValue is the ValueEncoderFunc for map[string]* types.
|
||||
func (dve DefaultValueEncoders) MapEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Kind() != reflect.Map || val.Type().Key().Kind() != reflect.String {
|
||||
return ValueEncoderError{Name: "MapEncodeValue", Kinds: []reflect.Kind{reflect.Map}, Received: val}
|
||||
}
|
||||
|
||||
if val.IsNil() {
|
||||
// If we have a nill map but we can't WriteNull, that means we're probably trying to encode
|
||||
// to a TopLevel document. We can't currently tell if this is what actually happened, but if
|
||||
// there's a deeper underlying problem, the error will also be returned from WriteDocument,
|
||||
// so just continue. The operations on a map reflection value are valid, so we can call
|
||||
// MapKeys within mapEncodeValue without a problem.
|
||||
err := vw.WriteNull()
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
dw, err := vw.WriteDocument()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return dve.mapEncodeValue(ec, dw, val, nil)
|
||||
}
|
||||
|
||||
// mapEncodeValue handles encoding of the values of a map. The collisionFn returns
|
||||
// true if the provided key exists, this is mainly used for inline maps in the
|
||||
// struct codec.
|
||||
func (dve DefaultValueEncoders) mapEncodeValue(ec EncodeContext, dw bsonrw.DocumentWriter, val reflect.Value, collisionFn func(string) bool) error {
|
||||
|
||||
encoder, err := ec.LookupEncoder(val.Type().Elem())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
keys := val.MapKeys()
|
||||
for _, key := range keys {
|
||||
if collisionFn != nil && collisionFn(key.String()) {
|
||||
return fmt.Errorf("Key %s of inlined map conflicts with a struct field name", key)
|
||||
}
|
||||
vw, err := dw.WriteDocumentElement(key.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if enc, ok := encoder.(ValueEncoder); ok {
|
||||
err = enc.EncodeValue(ec, vw, val.MapIndex(key))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
err = encoder.EncodeValue(ec, vw, val.MapIndex(key))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return dw.WriteDocumentEnd()
|
||||
}
|
||||
|
||||
// ArrayEncodeValue is the ValueEncoderFunc for array types.
|
||||
func (dve DefaultValueEncoders) ArrayEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Kind() != reflect.Array {
|
||||
return ValueEncoderError{Name: "ArrayEncodeValue", Kinds: []reflect.Kind{reflect.Array}, Received: val}
|
||||
}
|
||||
|
||||
// If we have a []primitive.E we want to treat it as a document instead of as an array.
|
||||
if val.Type().Elem() == tE {
|
||||
dw, err := vw.WriteDocument()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for idx := 0; idx < val.Len(); idx++ {
|
||||
e := val.Index(idx).Interface().(primitive.E)
|
||||
err = encodeElement(ec, dw, e)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return dw.WriteDocumentEnd()
|
||||
}
|
||||
|
||||
aw, err := vw.WriteArray()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
encoder, err := ec.LookupEncoder(val.Type().Elem())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for idx := 0; idx < val.Len(); idx++ {
|
||||
vw, err := aw.WriteArrayElement()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = encoder.EncodeValue(ec, vw, val.Index(idx))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return aw.WriteArrayEnd()
|
||||
}
|
||||
|
||||
// SliceEncodeValue is the ValueEncoderFunc for slice types.
|
||||
func (dve DefaultValueEncoders) SliceEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Kind() != reflect.Slice {
|
||||
return ValueEncoderError{Name: "SliceEncodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val}
|
||||
}
|
||||
|
||||
if val.IsNil() {
|
||||
return vw.WriteNull()
|
||||
}
|
||||
|
||||
// If we have a []primitive.E we want to treat it as a document instead of as an array.
|
||||
if val.Type().ConvertibleTo(tD) {
|
||||
d := val.Convert(tD).Interface().(primitive.D)
|
||||
|
||||
dw, err := vw.WriteDocument()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, e := range d {
|
||||
err = encodeElement(ec, dw, e)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return dw.WriteDocumentEnd()
|
||||
}
|
||||
|
||||
aw, err := vw.WriteArray()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
encoder, err := ec.LookupEncoder(val.Type().Elem())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for idx := 0; idx < val.Len(); idx++ {
|
||||
vw, err := aw.WriteArrayElement()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = encoder.EncodeValue(ec, vw, val.Index(idx))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return aw.WriteArrayEnd()
|
||||
}
|
||||
|
||||
// EmptyInterfaceEncodeValue is the ValueEncoderFunc for interface{}.
|
||||
func (dve DefaultValueEncoders) EmptyInterfaceEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tEmpty {
|
||||
return ValueEncoderError{Name: "EmptyInterfaceEncodeValue", Types: []reflect.Type{tEmpty}, Received: val}
|
||||
}
|
||||
|
||||
if val.IsNil() {
|
||||
return vw.WriteNull()
|
||||
}
|
||||
encoder, err := ec.LookupEncoder(val.Elem().Type())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return encoder.EncodeValue(ec, vw, val.Elem())
|
||||
}
|
||||
|
||||
// ValueMarshalerEncodeValue is the ValueEncoderFunc for ValueMarshaler implementations.
|
||||
func (dve DefaultValueEncoders) ValueMarshalerEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || !val.Type().Implements(tValueMarshaler) {
|
||||
return ValueEncoderError{Name: "ValueMarshalerEncodeValue", Types: []reflect.Type{tValueMarshaler}, Received: val}
|
||||
}
|
||||
|
||||
fn := val.Convert(tValueMarshaler).MethodByName("MarshalBSONValue")
|
||||
returns := fn.Call(nil)
|
||||
if !returns[2].IsNil() {
|
||||
return returns[2].Interface().(error)
|
||||
}
|
||||
t, data := returns[0].Interface().(bsontype.Type), returns[1].Interface().([]byte)
|
||||
return bsonrw.Copier{}.CopyValueFromBytes(vw, t, data)
|
||||
}
|
||||
|
||||
// MarshalerEncodeValue is the ValueEncoderFunc for Marshaler implementations.
|
||||
func (dve DefaultValueEncoders) MarshalerEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || !val.Type().Implements(tMarshaler) {
|
||||
return ValueEncoderError{Name: "MarshalerEncodeValue", Types: []reflect.Type{tMarshaler}, Received: val}
|
||||
}
|
||||
|
||||
fn := val.Convert(tMarshaler).MethodByName("MarshalBSON")
|
||||
returns := fn.Call(nil)
|
||||
if !returns[1].IsNil() {
|
||||
return returns[1].Interface().(error)
|
||||
}
|
||||
data := returns[0].Interface().([]byte)
|
||||
return bsonrw.Copier{}.CopyValueFromBytes(vw, bsontype.EmbeddedDocument, data)
|
||||
}
|
||||
|
||||
// ProxyEncodeValue is the ValueEncoderFunc for Proxy implementations.
|
||||
func (dve DefaultValueEncoders) ProxyEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || !val.Type().Implements(tProxy) {
|
||||
return ValueEncoderError{Name: "ProxyEncodeValue", Types: []reflect.Type{tProxy}, Received: val}
|
||||
}
|
||||
|
||||
fn := val.Convert(tProxy).MethodByName("ProxyBSON")
|
||||
returns := fn.Call(nil)
|
||||
if !returns[1].IsNil() {
|
||||
return returns[1].Interface().(error)
|
||||
}
|
||||
data := returns[0]
|
||||
var encoder ValueEncoder
|
||||
var err error
|
||||
if data.Elem().IsValid() {
|
||||
encoder, err = ec.LookupEncoder(data.Elem().Type())
|
||||
} else {
|
||||
encoder, err = ec.LookupEncoder(nil)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return encoder.EncodeValue(ec, vw, data.Elem())
|
||||
}
|
||||
|
||||
// JavaScriptEncodeValue is the ValueEncoderFunc for the primitive.JavaScript type.
|
||||
func (DefaultValueEncoders) JavaScriptEncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tJavaScript {
|
||||
return ValueEncoderError{Name: "JavaScriptEncodeValue", Types: []reflect.Type{tJavaScript}, Received: val}
|
||||
}
|
||||
|
||||
return vw.WriteJavascript(val.String())
|
||||
}
|
||||
|
||||
// SymbolEncodeValue is the ValueEncoderFunc for the primitive.Symbol type.
|
||||
func (DefaultValueEncoders) SymbolEncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tSymbol {
|
||||
return ValueEncoderError{Name: "SymbolEncodeValue", Types: []reflect.Type{tSymbol}, Received: val}
|
||||
}
|
||||
|
||||
return vw.WriteSymbol(val.String())
|
||||
}
|
||||
|
||||
// BinaryEncodeValue is the ValueEncoderFunc for Binary.
|
||||
func (DefaultValueEncoders) BinaryEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tBinary {
|
||||
return ValueEncoderError{Name: "BinaryEncodeValue", Types: []reflect.Type{tBinary}, Received: val}
|
||||
}
|
||||
b := val.Interface().(primitive.Binary)
|
||||
|
||||
return vw.WriteBinaryWithSubtype(b.Data, b.Subtype)
|
||||
}
|
||||
|
||||
// UndefinedEncodeValue is the ValueEncoderFunc for Undefined.
|
||||
func (DefaultValueEncoders) UndefinedEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tUndefined {
|
||||
return ValueEncoderError{Name: "UndefinedEncodeValue", Types: []reflect.Type{tUndefined}, Received: val}
|
||||
}
|
||||
|
||||
return vw.WriteUndefined()
|
||||
}
|
||||
|
||||
// DateTimeEncodeValue is the ValueEncoderFunc for DateTime.
|
||||
func (DefaultValueEncoders) DateTimeEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tDateTime {
|
||||
return ValueEncoderError{Name: "DateTimeEncodeValue", Types: []reflect.Type{tDateTime}, Received: val}
|
||||
}
|
||||
|
||||
return vw.WriteDateTime(val.Int())
|
||||
}
|
||||
|
||||
// NullEncodeValue is the ValueEncoderFunc for Null.
|
||||
func (DefaultValueEncoders) NullEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tNull {
|
||||
return ValueEncoderError{Name: "NullEncodeValue", Types: []reflect.Type{tNull}, Received: val}
|
||||
}
|
||||
|
||||
return vw.WriteNull()
|
||||
}
|
||||
|
||||
// RegexEncodeValue is the ValueEncoderFunc for Regex.
|
||||
func (DefaultValueEncoders) RegexEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tRegex {
|
||||
return ValueEncoderError{Name: "RegexEncodeValue", Types: []reflect.Type{tRegex}, Received: val}
|
||||
}
|
||||
|
||||
regex := val.Interface().(primitive.Regex)
|
||||
|
||||
return vw.WriteRegex(regex.Pattern, regex.Options)
|
||||
}
|
||||
|
||||
// DBPointerEncodeValue is the ValueEncoderFunc for DBPointer.
|
||||
func (DefaultValueEncoders) DBPointerEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tDBPointer {
|
||||
return ValueEncoderError{Name: "DBPointerEncodeValue", Types: []reflect.Type{tDBPointer}, Received: val}
|
||||
}
|
||||
|
||||
dbp := val.Interface().(primitive.DBPointer)
|
||||
|
||||
return vw.WriteDBPointer(dbp.DB, dbp.Pointer)
|
||||
}
|
||||
|
||||
// TimestampEncodeValue is the ValueEncoderFunc for Timestamp.
|
||||
func (DefaultValueEncoders) TimestampEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tTimestamp {
|
||||
return ValueEncoderError{Name: "TimestampEncodeValue", Types: []reflect.Type{tTimestamp}, Received: val}
|
||||
}
|
||||
|
||||
ts := val.Interface().(primitive.Timestamp)
|
||||
|
||||
return vw.WriteTimestamp(ts.T, ts.I)
|
||||
}
|
||||
|
||||
// MinKeyEncodeValue is the ValueEncoderFunc for MinKey.
|
||||
func (DefaultValueEncoders) MinKeyEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tMinKey {
|
||||
return ValueEncoderError{Name: "MinKeyEncodeValue", Types: []reflect.Type{tMinKey}, Received: val}
|
||||
}
|
||||
|
||||
return vw.WriteMinKey()
|
||||
}
|
||||
|
||||
// MaxKeyEncodeValue is the ValueEncoderFunc for MaxKey.
|
||||
func (DefaultValueEncoders) MaxKeyEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tMaxKey {
|
||||
return ValueEncoderError{Name: "MaxKeyEncodeValue", Types: []reflect.Type{tMaxKey}, Received: val}
|
||||
}
|
||||
|
||||
return vw.WriteMaxKey()
|
||||
}
|
||||
|
||||
// CoreDocumentEncodeValue is the ValueEncoderFunc for bsoncore.Document.
|
||||
func (DefaultValueEncoders) CoreDocumentEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tCoreDocument {
|
||||
return ValueEncoderError{Name: "CoreDocumentEncodeValue", Types: []reflect.Type{tCoreDocument}, Received: val}
|
||||
}
|
||||
|
||||
cdoc := val.Interface().(bsoncore.Document)
|
||||
|
||||
return bsonrw.Copier{}.CopyDocumentFromBytes(vw, cdoc)
|
||||
}
|
||||
|
||||
// CodeWithScopeEncodeValue is the ValueEncoderFunc for CodeWithScope.
|
||||
func (dve DefaultValueEncoders) CodeWithScopeEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tCodeWithScope {
|
||||
return ValueEncoderError{Name: "CodeWithScopeEncodeValue", Types: []reflect.Type{tCodeWithScope}, Received: val}
|
||||
}
|
||||
|
||||
cws := val.Interface().(primitive.CodeWithScope)
|
||||
|
||||
dw, err := vw.WriteCodeWithScope(string(cws.Code))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sw := sliceWriterPool.Get().(*bsonrw.SliceWriter)
|
||||
defer sliceWriterPool.Put(sw)
|
||||
*sw = (*sw)[:0]
|
||||
|
||||
scopeVW := bvwPool.Get(sw)
|
||||
defer bvwPool.Put(scopeVW)
|
||||
|
||||
encoder, err := ec.LookupEncoder(reflect.TypeOf(cws.Scope))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = encoder.EncodeValue(ec, scopeVW, reflect.ValueOf(cws.Scope))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = bsonrw.Copier{}.CopyBytesToDocumentWriter(dw, *sw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return dw.WriteDocumentEnd()
|
||||
}
|
61
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/doc.go
generated
vendored
Normal file
61
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/doc.go
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
// Package bsoncodec provides a system for encoding values to BSON representations and decoding
|
||||
// values from BSON representations. This package considers both binary BSON and ExtendedJSON as
|
||||
// BSON representations. The types in this package enable a flexible system for handling this
|
||||
// encoding and decoding.
|
||||
//
|
||||
// The codec system is composed of two parts:
|
||||
//
|
||||
// 1) ValueEncoders and ValueDecoders that handle encoding and decoding Go values to and from BSON
|
||||
// representations.
|
||||
//
|
||||
// 2) A Registry that holds these ValueEncoders and ValueDecoders and provides methods for
|
||||
// retrieving them.
|
||||
//
|
||||
// ValueEncoders and ValueDecoders
|
||||
//
|
||||
// The ValueEncoder interface is implemented by types that can encode a provided Go type to BSON.
|
||||
// The value to encode is provided as a reflect.Value and a bsonrw.ValueWriter is used within the
|
||||
// EncodeValue method to actually create the BSON representation. For convenience, ValueEncoderFunc
|
||||
// is provided to allow use of a function with the correct signature as a ValueEncoder. An
|
||||
// EncodeContext instance is provided to allow implementations to lookup further ValueEncoders and
|
||||
// to provide configuration information.
|
||||
//
|
||||
// The ValueDecoder interface is the inverse of the ValueEncoder. Implementations should ensure that
|
||||
// the value they receive is settable. Similar to ValueEncoderFunc, ValueDecoderFunc is provided to
|
||||
// allow the use of a function with the correct signature as a ValueDecoder. A DecodeContext
|
||||
// instance is provided and serves similar functionality to the EncodeContext.
|
||||
//
|
||||
// Registry and RegistryBuilder
|
||||
//
|
||||
// A Registry is an immutable store for ValueEncoders, ValueDecoders, and a type map. For looking up
|
||||
// ValueEncoders and Decoders the Registry first attempts to find a ValueEncoder or ValueDecoder for
|
||||
// the type provided; if one cannot be found it then checks to see if a registered ValueEncoder or
|
||||
// ValueDecoder exists for an interface the type implements. Finally, the reflect.Kind of the type
|
||||
// is used to lookup a default ValueEncoder or ValueDecoder for that kind. If no ValueEncoder or
|
||||
// ValueDecoder can be found, an error is returned.
|
||||
//
|
||||
// The Registry also holds a type map. This allows users to retrieve the Go type that should be used
|
||||
// when decoding a BSON value into an empty interface. This is primarily only used for the empty
|
||||
// interface ValueDecoder.
|
||||
//
|
||||
// A RegistryBuilder is used to construct a Registry. The Register methods are used to associate
|
||||
// either a reflect.Type or a reflect.Kind with a ValueEncoder or ValueDecoder. A RegistryBuilder
|
||||
// returned from NewRegistryBuilder contains no registered ValueEncoders nor ValueDecoders and
|
||||
// contains an empty type map.
|
||||
//
|
||||
// The RegisterTypeMapEntry method handles associating a BSON type with a Go type. For example, if
|
||||
// you want to decode BSON int64 and int32 values into Go int instances, you would do the following:
|
||||
//
|
||||
// var regbuilder *RegistryBuilder = ... intType := reflect.TypeOf(int(0))
|
||||
// regbuilder.RegisterTypeMapEntry(bsontype.Int64, intType).RegisterTypeMapEntry(bsontype.Int32,
|
||||
// intType)
|
||||
//
|
||||
// DefaultValueEncoders and DefaultValueDecoders
|
||||
//
|
||||
// The DefaultValueEncoders and DefaultValueDecoders types provide a full set of ValueEncoders and
|
||||
// ValueDecoders for handling a wide range of Go types, including all of the types within the
|
||||
// primitive package. To make registering these codecs easier, a helper method on each type is
|
||||
// provided. For the DefaultValueEncoders type the method is called RegisterDefaultEncoders and for
|
||||
// the DefaultValueDecoders type the method is called RegisterDefaultDecoders, this method also
|
||||
// handles registering type map entries for each BSON type.
|
||||
package bsoncodec
|
65
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/mode.go
generated
vendored
Normal file
65
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/mode.go
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
// Copyright (C) MongoDB, Inc. 2017-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package bsoncodec
|
||||
|
||||
import "fmt"
|
||||
|
||||
type mode int
|
||||
|
||||
const (
|
||||
_ mode = iota
|
||||
mTopLevel
|
||||
mDocument
|
||||
mArray
|
||||
mValue
|
||||
mElement
|
||||
mCodeWithScope
|
||||
mSpacer
|
||||
)
|
||||
|
||||
func (m mode) String() string {
|
||||
var str string
|
||||
|
||||
switch m {
|
||||
case mTopLevel:
|
||||
str = "TopLevel"
|
||||
case mDocument:
|
||||
str = "DocumentMode"
|
||||
case mArray:
|
||||
str = "ArrayMode"
|
||||
case mValue:
|
||||
str = "ValueMode"
|
||||
case mElement:
|
||||
str = "ElementMode"
|
||||
case mCodeWithScope:
|
||||
str = "CodeWithScopeMode"
|
||||
case mSpacer:
|
||||
str = "CodeWithScopeSpacerFrame"
|
||||
default:
|
||||
str = "UnknownMode"
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
// TransitionError is an error returned when an invalid progressing a
|
||||
// ValueReader or ValueWriter state machine occurs.
|
||||
type TransitionError struct {
|
||||
parent mode
|
||||
current mode
|
||||
destination mode
|
||||
}
|
||||
|
||||
func (te TransitionError) Error() string {
|
||||
if te.destination == mode(0) {
|
||||
return fmt.Sprintf("invalid state transition: cannot read/write value while in %s", te.current)
|
||||
}
|
||||
if te.parent == mode(0) {
|
||||
return fmt.Sprintf("invalid state transition: %s -> %s", te.current, te.destination)
|
||||
}
|
||||
return fmt.Sprintf("invalid state transition: %s -> %s; parent %s", te.current, te.destination, te.parent)
|
||||
}
|
110
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/pointer_codec.go
generated
vendored
Normal file
110
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/pointer_codec.go
generated
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
// Copyright (C) MongoDB, Inc. 2017-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package bsoncodec
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/bsonrw"
|
||||
"go.mongodb.org/mongo-driver/bson/bsontype"
|
||||
)
|
||||
|
||||
var defaultPointerCodec = &PointerCodec{
|
||||
ecache: make(map[reflect.Type]ValueEncoder),
|
||||
dcache: make(map[reflect.Type]ValueDecoder),
|
||||
}
|
||||
|
||||
var _ ValueEncoder = &PointerCodec{}
|
||||
var _ ValueDecoder = &PointerCodec{}
|
||||
|
||||
// PointerCodec is the Codec used for pointers.
|
||||
type PointerCodec struct {
|
||||
ecache map[reflect.Type]ValueEncoder
|
||||
dcache map[reflect.Type]ValueDecoder
|
||||
l sync.RWMutex
|
||||
}
|
||||
|
||||
// NewPointerCodec returns a PointerCodec that has been initialized.
|
||||
func NewPointerCodec() *PointerCodec {
|
||||
return &PointerCodec{
|
||||
ecache: make(map[reflect.Type]ValueEncoder),
|
||||
dcache: make(map[reflect.Type]ValueDecoder),
|
||||
}
|
||||
}
|
||||
|
||||
// EncodeValue handles encoding a pointer by either encoding it to BSON Null if the pointer is nil
|
||||
// or looking up an encoder for the type of value the pointer points to.
|
||||
func (pc *PointerCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if val.Kind() != reflect.Ptr {
|
||||
if !val.IsValid() {
|
||||
return vw.WriteNull()
|
||||
}
|
||||
return ValueEncoderError{Name: "PointerCodec.EncodeValue", Kinds: []reflect.Kind{reflect.Ptr}, Received: val}
|
||||
}
|
||||
|
||||
if val.IsNil() {
|
||||
return vw.WriteNull()
|
||||
}
|
||||
|
||||
pc.l.RLock()
|
||||
enc, ok := pc.ecache[val.Type()]
|
||||
pc.l.RUnlock()
|
||||
if ok {
|
||||
if enc == nil {
|
||||
return ErrNoEncoder{Type: val.Type()}
|
||||
}
|
||||
return enc.EncodeValue(ec, vw, val.Elem())
|
||||
}
|
||||
|
||||
enc, err := ec.LookupEncoder(val.Type().Elem())
|
||||
pc.l.Lock()
|
||||
pc.ecache[val.Type()] = enc
|
||||
pc.l.Unlock()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return enc.EncodeValue(ec, vw, val.Elem())
|
||||
}
|
||||
|
||||
// DecodeValue handles decoding a pointer by looking up a decoder for the type it points to and
|
||||
// using that to decode. If the BSON value is Null, this method will set the pointer to nil.
|
||||
func (pc *PointerCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if !val.CanSet() || val.Kind() != reflect.Ptr {
|
||||
return ValueDecoderError{Name: "PointerCodec.DecodeValue", Kinds: []reflect.Kind{reflect.Ptr}, Received: val}
|
||||
}
|
||||
|
||||
if vr.Type() == bsontype.Null {
|
||||
val.Set(reflect.Zero(val.Type()))
|
||||
return vr.ReadNull()
|
||||
}
|
||||
|
||||
if val.IsNil() {
|
||||
val.Set(reflect.New(val.Type().Elem()))
|
||||
}
|
||||
|
||||
pc.l.RLock()
|
||||
dec, ok := pc.dcache[val.Type()]
|
||||
pc.l.RUnlock()
|
||||
if ok {
|
||||
if dec == nil {
|
||||
return ErrNoDecoder{Type: val.Type()}
|
||||
}
|
||||
return dec.DecodeValue(dc, vr, val.Elem())
|
||||
}
|
||||
|
||||
dec, err := dc.LookupDecoder(val.Type().Elem())
|
||||
pc.l.Lock()
|
||||
pc.dcache[val.Type()] = dec
|
||||
pc.l.Unlock()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return dec.DecodeValue(dc, vr, val.Elem())
|
||||
}
|
14
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/proxy.go
generated
vendored
Normal file
14
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/proxy.go
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright (C) MongoDB, Inc. 2017-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package bsoncodec
|
||||
|
||||
// Proxy is an interface implemented by types that cannot themselves be directly encoded. Types
|
||||
// that implement this interface with have ProxyBSON called during the encoding process and that
|
||||
// value will be encoded in place for the implementer.
|
||||
type Proxy interface {
|
||||
ProxyBSON() (interface{}, error)
|
||||
}
|
384
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go
generated
vendored
Normal file
384
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go
generated
vendored
Normal file
@@ -0,0 +1,384 @@
|
||||
// Copyright (C) MongoDB, Inc. 2017-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package bsoncodec
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/bsontype"
|
||||
)
|
||||
|
||||
// ErrNilType is returned when nil is passed to either LookupEncoder or LookupDecoder.
|
||||
var ErrNilType = errors.New("cannot perform a decoder lookup on <nil>")
|
||||
|
||||
// ErrNotPointer is returned when a non-pointer type is provided to LookupDecoder.
|
||||
var ErrNotPointer = errors.New("non-pointer provided to LookupDecoder")
|
||||
|
||||
// ErrNoEncoder is returned when there wasn't an encoder available for a type.
|
||||
type ErrNoEncoder struct {
|
||||
Type reflect.Type
|
||||
}
|
||||
|
||||
func (ene ErrNoEncoder) Error() string {
|
||||
if ene.Type == nil {
|
||||
return "no encoder found for <nil>"
|
||||
}
|
||||
return "no encoder found for " + ene.Type.String()
|
||||
}
|
||||
|
||||
// ErrNoDecoder is returned when there wasn't a decoder available for a type.
|
||||
type ErrNoDecoder struct {
|
||||
Type reflect.Type
|
||||
}
|
||||
|
||||
func (end ErrNoDecoder) Error() string {
|
||||
return "no decoder found for " + end.Type.String()
|
||||
}
|
||||
|
||||
// ErrNoTypeMapEntry is returned when there wasn't a type available for the provided BSON type.
|
||||
type ErrNoTypeMapEntry struct {
|
||||
Type bsontype.Type
|
||||
}
|
||||
|
||||
func (entme ErrNoTypeMapEntry) Error() string {
|
||||
return "no type map entry found for " + entme.Type.String()
|
||||
}
|
||||
|
||||
// ErrNotInterface is returned when the provided type is not an interface.
|
||||
var ErrNotInterface = errors.New("The provided type is not an interface")
|
||||
|
||||
var defaultRegistry *Registry
|
||||
|
||||
func init() {
|
||||
defaultRegistry = buildDefaultRegistry()
|
||||
}
|
||||
|
||||
// A RegistryBuilder is used to build a Registry. This type is not goroutine
|
||||
// safe.
|
||||
type RegistryBuilder struct {
|
||||
typeEncoders map[reflect.Type]ValueEncoder
|
||||
interfaceEncoders []interfaceValueEncoder
|
||||
kindEncoders map[reflect.Kind]ValueEncoder
|
||||
|
||||
typeDecoders map[reflect.Type]ValueDecoder
|
||||
interfaceDecoders []interfaceValueDecoder
|
||||
kindDecoders map[reflect.Kind]ValueDecoder
|
||||
|
||||
typeMap map[bsontype.Type]reflect.Type
|
||||
}
|
||||
|
||||
// A Registry is used to store and retrieve codecs for types and interfaces. This type is the main
|
||||
// typed passed around and Encoders and Decoders are constructed from it.
|
||||
type Registry struct {
|
||||
typeEncoders map[reflect.Type]ValueEncoder
|
||||
typeDecoders map[reflect.Type]ValueDecoder
|
||||
|
||||
interfaceEncoders []interfaceValueEncoder
|
||||
interfaceDecoders []interfaceValueDecoder
|
||||
|
||||
kindEncoders map[reflect.Kind]ValueEncoder
|
||||
kindDecoders map[reflect.Kind]ValueDecoder
|
||||
|
||||
typeMap map[bsontype.Type]reflect.Type
|
||||
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
// NewRegistryBuilder creates a new empty RegistryBuilder.
|
||||
func NewRegistryBuilder() *RegistryBuilder {
|
||||
return &RegistryBuilder{
|
||||
typeEncoders: make(map[reflect.Type]ValueEncoder),
|
||||
typeDecoders: make(map[reflect.Type]ValueDecoder),
|
||||
|
||||
interfaceEncoders: make([]interfaceValueEncoder, 0),
|
||||
interfaceDecoders: make([]interfaceValueDecoder, 0),
|
||||
|
||||
kindEncoders: make(map[reflect.Kind]ValueEncoder),
|
||||
kindDecoders: make(map[reflect.Kind]ValueDecoder),
|
||||
|
||||
typeMap: make(map[bsontype.Type]reflect.Type),
|
||||
}
|
||||
}
|
||||
|
||||
func buildDefaultRegistry() *Registry {
|
||||
rb := NewRegistryBuilder()
|
||||
defaultValueEncoders.RegisterDefaultEncoders(rb)
|
||||
defaultValueDecoders.RegisterDefaultDecoders(rb)
|
||||
return rb.Build()
|
||||
}
|
||||
|
||||
// RegisterCodec will register the provided ValueCodec for the provided type.
|
||||
func (rb *RegistryBuilder) RegisterCodec(t reflect.Type, codec ValueCodec) *RegistryBuilder {
|
||||
rb.RegisterEncoder(t, codec)
|
||||
rb.RegisterDecoder(t, codec)
|
||||
return rb
|
||||
}
|
||||
|
||||
// RegisterEncoder will register the provided ValueEncoder to the provided type.
|
||||
//
|
||||
// The type registered will be used directly, so an encoder can be registered for a type and a
|
||||
// different encoder can be registered for a pointer to that type.
|
||||
func (rb *RegistryBuilder) RegisterEncoder(t reflect.Type, enc ValueEncoder) *RegistryBuilder {
|
||||
if t == tEmpty {
|
||||
rb.typeEncoders[t] = enc
|
||||
return rb
|
||||
}
|
||||
switch t.Kind() {
|
||||
case reflect.Interface:
|
||||
for idx, ir := range rb.interfaceEncoders {
|
||||
if ir.i == t {
|
||||
rb.interfaceEncoders[idx].ve = enc
|
||||
return rb
|
||||
}
|
||||
}
|
||||
|
||||
rb.interfaceEncoders = append(rb.interfaceEncoders, interfaceValueEncoder{i: t, ve: enc})
|
||||
default:
|
||||
rb.typeEncoders[t] = enc
|
||||
}
|
||||
return rb
|
||||
}
|
||||
|
||||
// RegisterDecoder will register the provided ValueDecoder to the provided type.
|
||||
//
|
||||
// The type registered will be used directly, so a decoder can be registered for a type and a
|
||||
// different decoder can be registered for a pointer to that type.
|
||||
func (rb *RegistryBuilder) RegisterDecoder(t reflect.Type, dec ValueDecoder) *RegistryBuilder {
|
||||
if t == nil {
|
||||
rb.typeDecoders[nil] = dec
|
||||
return rb
|
||||
}
|
||||
if t == tEmpty {
|
||||
rb.typeDecoders[t] = dec
|
||||
return rb
|
||||
}
|
||||
switch t.Kind() {
|
||||
case reflect.Interface:
|
||||
for idx, ir := range rb.interfaceDecoders {
|
||||
if ir.i == t {
|
||||
rb.interfaceDecoders[idx].vd = dec
|
||||
return rb
|
||||
}
|
||||
}
|
||||
|
||||
rb.interfaceDecoders = append(rb.interfaceDecoders, interfaceValueDecoder{i: t, vd: dec})
|
||||
default:
|
||||
rb.typeDecoders[t] = dec
|
||||
}
|
||||
return rb
|
||||
}
|
||||
|
||||
// RegisterDefaultEncoder will registr the provided ValueEncoder to the provided
|
||||
// kind.
|
||||
func (rb *RegistryBuilder) RegisterDefaultEncoder(kind reflect.Kind, enc ValueEncoder) *RegistryBuilder {
|
||||
rb.kindEncoders[kind] = enc
|
||||
return rb
|
||||
}
|
||||
|
||||
// RegisterDefaultDecoder will register the provided ValueDecoder to the
|
||||
// provided kind.
|
||||
func (rb *RegistryBuilder) RegisterDefaultDecoder(kind reflect.Kind, dec ValueDecoder) *RegistryBuilder {
|
||||
rb.kindDecoders[kind] = dec
|
||||
return rb
|
||||
}
|
||||
|
||||
// RegisterTypeMapEntry will register the provided type to the BSON type. The primary usage for this
|
||||
// mapping is decoding situations where an empty interface is used and a default type needs to be
|
||||
// created and decoded into.
|
||||
//
|
||||
// NOTE: It is unlikely that registering a type for BSON Embedded Document is actually desired. By
|
||||
// registering a type map entry for BSON Embedded Document the type registered will be used in any
|
||||
// case where a BSON Embedded Document will be decoded into an empty interface. For example, if you
|
||||
// register primitive.M, the EmptyInterface decoder will always use primitive.M, even if an ancestor
|
||||
// was a primitive.D.
|
||||
func (rb *RegistryBuilder) RegisterTypeMapEntry(bt bsontype.Type, rt reflect.Type) *RegistryBuilder {
|
||||
rb.typeMap[bt] = rt
|
||||
return rb
|
||||
}
|
||||
|
||||
// Build creates a Registry from the current state of this RegistryBuilder.
|
||||
func (rb *RegistryBuilder) Build() *Registry {
|
||||
registry := new(Registry)
|
||||
|
||||
registry.typeEncoders = make(map[reflect.Type]ValueEncoder)
|
||||
for t, enc := range rb.typeEncoders {
|
||||
registry.typeEncoders[t] = enc
|
||||
}
|
||||
|
||||
registry.typeDecoders = make(map[reflect.Type]ValueDecoder)
|
||||
for t, dec := range rb.typeDecoders {
|
||||
registry.typeDecoders[t] = dec
|
||||
}
|
||||
|
||||
registry.interfaceEncoders = make([]interfaceValueEncoder, len(rb.interfaceEncoders))
|
||||
copy(registry.interfaceEncoders, rb.interfaceEncoders)
|
||||
|
||||
registry.interfaceDecoders = make([]interfaceValueDecoder, len(rb.interfaceDecoders))
|
||||
copy(registry.interfaceDecoders, rb.interfaceDecoders)
|
||||
|
||||
registry.kindEncoders = make(map[reflect.Kind]ValueEncoder)
|
||||
for kind, enc := range rb.kindEncoders {
|
||||
registry.kindEncoders[kind] = enc
|
||||
}
|
||||
|
||||
registry.kindDecoders = make(map[reflect.Kind]ValueDecoder)
|
||||
for kind, dec := range rb.kindDecoders {
|
||||
registry.kindDecoders[kind] = dec
|
||||
}
|
||||
|
||||
registry.typeMap = make(map[bsontype.Type]reflect.Type)
|
||||
for bt, rt := range rb.typeMap {
|
||||
registry.typeMap[bt] = rt
|
||||
}
|
||||
|
||||
return registry
|
||||
}
|
||||
|
||||
// LookupEncoder will inspect the registry for an encoder that satisfies the
|
||||
// type provided. An encoder registered for a specific type will take
|
||||
// precedence over an encoder registered for an interface the type satisfies,
|
||||
// which takes precedence over an encoder for the reflect.Kind of the value. If
|
||||
// no encoder can be found, an error is returned.
|
||||
func (r *Registry) LookupEncoder(t reflect.Type) (ValueEncoder, error) {
|
||||
encodererr := ErrNoEncoder{Type: t}
|
||||
r.mu.RLock()
|
||||
enc, found := r.lookupTypeEncoder(t)
|
||||
r.mu.RUnlock()
|
||||
if found {
|
||||
if enc == nil {
|
||||
return nil, ErrNoEncoder{Type: t}
|
||||
}
|
||||
return enc, nil
|
||||
}
|
||||
|
||||
enc, found = r.lookupInterfaceEncoder(t)
|
||||
if found {
|
||||
r.mu.Lock()
|
||||
r.typeEncoders[t] = enc
|
||||
r.mu.Unlock()
|
||||
return enc, nil
|
||||
}
|
||||
|
||||
if t == nil {
|
||||
r.mu.Lock()
|
||||
r.typeEncoders[t] = nil
|
||||
r.mu.Unlock()
|
||||
return nil, encodererr
|
||||
}
|
||||
|
||||
enc, found = r.kindEncoders[t.Kind()]
|
||||
if !found {
|
||||
r.mu.Lock()
|
||||
r.typeEncoders[t] = nil
|
||||
r.mu.Unlock()
|
||||
return nil, encodererr
|
||||
}
|
||||
|
||||
r.mu.Lock()
|
||||
r.typeEncoders[t] = enc
|
||||
r.mu.Unlock()
|
||||
return enc, nil
|
||||
}
|
||||
|
||||
func (r *Registry) lookupTypeEncoder(t reflect.Type) (ValueEncoder, bool) {
|
||||
enc, found := r.typeEncoders[t]
|
||||
return enc, found
|
||||
}
|
||||
|
||||
func (r *Registry) lookupInterfaceEncoder(t reflect.Type) (ValueEncoder, bool) {
|
||||
if t == nil {
|
||||
return nil, false
|
||||
}
|
||||
for _, ienc := range r.interfaceEncoders {
|
||||
if !t.Implements(ienc.i) {
|
||||
continue
|
||||
}
|
||||
|
||||
return ienc.ve, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// LookupDecoder will inspect the registry for a decoder that satisfies the
|
||||
// type provided. A decoder registered for a specific type will take
|
||||
// precedence over a decoder registered for an interface the type satisfies,
|
||||
// which takes precedence over a decoder for the reflect.Kind of the value. If
|
||||
// no decoder can be found, an error is returned.
|
||||
func (r *Registry) LookupDecoder(t reflect.Type) (ValueDecoder, error) {
|
||||
if t == nil {
|
||||
return nil, ErrNilType
|
||||
}
|
||||
decodererr := ErrNoDecoder{Type: t}
|
||||
r.mu.RLock()
|
||||
dec, found := r.lookupTypeDecoder(t)
|
||||
r.mu.RUnlock()
|
||||
if found {
|
||||
if dec == nil {
|
||||
return nil, ErrNoDecoder{Type: t}
|
||||
}
|
||||
return dec, nil
|
||||
}
|
||||
|
||||
dec, found = r.lookupInterfaceDecoder(t)
|
||||
if found {
|
||||
r.mu.Lock()
|
||||
r.typeDecoders[t] = dec
|
||||
r.mu.Unlock()
|
||||
return dec, nil
|
||||
}
|
||||
|
||||
dec, found = r.kindDecoders[t.Kind()]
|
||||
if !found {
|
||||
r.mu.Lock()
|
||||
r.typeDecoders[t] = nil
|
||||
r.mu.Unlock()
|
||||
return nil, decodererr
|
||||
}
|
||||
|
||||
r.mu.Lock()
|
||||
r.typeDecoders[t] = dec
|
||||
r.mu.Unlock()
|
||||
return dec, nil
|
||||
}
|
||||
|
||||
func (r *Registry) lookupTypeDecoder(t reflect.Type) (ValueDecoder, bool) {
|
||||
dec, found := r.typeDecoders[t]
|
||||
return dec, found
|
||||
}
|
||||
|
||||
func (r *Registry) lookupInterfaceDecoder(t reflect.Type) (ValueDecoder, bool) {
|
||||
for _, idec := range r.interfaceDecoders {
|
||||
if !t.Implements(idec.i) && !reflect.PtrTo(t).Implements(idec.i) {
|
||||
continue
|
||||
}
|
||||
|
||||
return idec.vd, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// LookupTypeMapEntry inspects the registry's type map for a Go type for the corresponding BSON
|
||||
// type. If no type is found, ErrNoTypeMapEntry is returned.
|
||||
func (r *Registry) LookupTypeMapEntry(bt bsontype.Type) (reflect.Type, error) {
|
||||
t, ok := r.typeMap[bt]
|
||||
if !ok || t == nil {
|
||||
return nil, ErrNoTypeMapEntry{Type: bt}
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
||||
type interfaceValueEncoder struct {
|
||||
i reflect.Type
|
||||
ve ValueEncoder
|
||||
}
|
||||
|
||||
type interfaceValueDecoder struct {
|
||||
i reflect.Type
|
||||
vd ValueDecoder
|
||||
}
|
359
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_codec.go
generated
vendored
Normal file
359
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_codec.go
generated
vendored
Normal file
@@ -0,0 +1,359 @@
|
||||
// Copyright (C) MongoDB, Inc. 2017-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package bsoncodec
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/bsonrw"
|
||||
"go.mongodb.org/mongo-driver/bson/bsontype"
|
||||
)
|
||||
|
||||
var defaultStructCodec = &StructCodec{
|
||||
cache: make(map[reflect.Type]*structDescription),
|
||||
parser: DefaultStructTagParser,
|
||||
}
|
||||
|
||||
// Zeroer allows custom struct types to implement a report of zero
|
||||
// state. All struct types that don't implement Zeroer or where IsZero
|
||||
// returns false are considered to be not zero.
|
||||
type Zeroer interface {
|
||||
IsZero() bool
|
||||
}
|
||||
|
||||
// StructCodec is the Codec used for struct values.
|
||||
type StructCodec struct {
|
||||
cache map[reflect.Type]*structDescription
|
||||
l sync.RWMutex
|
||||
parser StructTagParser
|
||||
}
|
||||
|
||||
var _ ValueEncoder = &StructCodec{}
|
||||
var _ ValueDecoder = &StructCodec{}
|
||||
|
||||
// NewStructCodec returns a StructCodec that uses p for struct tag parsing.
|
||||
func NewStructCodec(p StructTagParser) (*StructCodec, error) {
|
||||
if p == nil {
|
||||
return nil, errors.New("a StructTagParser must be provided to NewStructCodec")
|
||||
}
|
||||
|
||||
return &StructCodec{
|
||||
cache: make(map[reflect.Type]*structDescription),
|
||||
parser: p,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// EncodeValue handles encoding generic struct types.
|
||||
func (sc *StructCodec) EncodeValue(r EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Kind() != reflect.Struct {
|
||||
return ValueEncoderError{Name: "StructCodec.EncodeValue", Kinds: []reflect.Kind{reflect.Struct}, Received: val}
|
||||
}
|
||||
|
||||
sd, err := sc.describeStruct(r.Registry, val.Type())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dw, err := vw.WriteDocument()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var rv reflect.Value
|
||||
for _, desc := range sd.fl {
|
||||
if desc.inline == nil {
|
||||
rv = val.Field(desc.idx)
|
||||
} else {
|
||||
rv = val.FieldByIndex(desc.inline)
|
||||
}
|
||||
|
||||
if desc.encoder == nil {
|
||||
return ErrNoEncoder{Type: rv.Type()}
|
||||
}
|
||||
|
||||
encoder := desc.encoder
|
||||
|
||||
iszero := sc.isZero
|
||||
if iz, ok := encoder.(CodecZeroer); ok {
|
||||
iszero = iz.IsTypeZero
|
||||
}
|
||||
|
||||
if desc.omitEmpty && iszero(rv.Interface()) {
|
||||
continue
|
||||
}
|
||||
|
||||
vw2, err := dw.WriteDocumentElement(desc.name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ectx := EncodeContext{Registry: r.Registry, MinSize: desc.minSize}
|
||||
err = encoder.EncodeValue(ectx, vw2, rv)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if sd.inlineMap >= 0 {
|
||||
rv := val.Field(sd.inlineMap)
|
||||
collisionFn := func(key string) bool {
|
||||
_, exists := sd.fm[key]
|
||||
return exists
|
||||
}
|
||||
|
||||
return defaultValueEncoders.mapEncodeValue(r, dw, rv, collisionFn)
|
||||
}
|
||||
|
||||
return dw.WriteDocumentEnd()
|
||||
}
|
||||
|
||||
// DecodeValue implements the Codec interface.
|
||||
// By default, map types in val will not be cleared. If a map has existing key/value pairs, it will be extended with the new ones from vr.
|
||||
// For slices, the decoder will set the length of the slice to zero and append all elements. The underlying array will not be cleared.
|
||||
func (sc *StructCodec) DecodeValue(r DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if !val.CanSet() || val.Kind() != reflect.Struct {
|
||||
return ValueDecoderError{Name: "StructCodec.DecodeValue", Kinds: []reflect.Kind{reflect.Struct}, Received: val}
|
||||
}
|
||||
|
||||
switch vr.Type() {
|
||||
case bsontype.Type(0), bsontype.EmbeddedDocument:
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into a %s", vr.Type(), val.Type())
|
||||
}
|
||||
|
||||
sd, err := sc.describeStruct(r.Registry, val.Type())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var decoder ValueDecoder
|
||||
var inlineMap reflect.Value
|
||||
if sd.inlineMap >= 0 {
|
||||
inlineMap = val.Field(sd.inlineMap)
|
||||
if inlineMap.IsNil() {
|
||||
inlineMap.Set(reflect.MakeMap(inlineMap.Type()))
|
||||
}
|
||||
decoder, err = r.LookupDecoder(inlineMap.Type().Elem())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
dr, err := vr.ReadDocument()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for {
|
||||
name, vr, err := dr.ReadElement()
|
||||
if err == bsonrw.ErrEOD {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fd, exists := sd.fm[name]
|
||||
if !exists {
|
||||
if sd.inlineMap < 0 {
|
||||
// The encoding/json package requires a flag to return on error for non-existent fields.
|
||||
// This functionality seems appropriate for the struct codec.
|
||||
err = vr.Skip()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
elem := reflect.New(inlineMap.Type().Elem()).Elem()
|
||||
err = decoder.DecodeValue(r, vr, elem)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
inlineMap.SetMapIndex(reflect.ValueOf(name), elem)
|
||||
continue
|
||||
}
|
||||
|
||||
var field reflect.Value
|
||||
if fd.inline == nil {
|
||||
field = val.Field(fd.idx)
|
||||
} else {
|
||||
field = val.FieldByIndex(fd.inline)
|
||||
}
|
||||
|
||||
if !field.CanSet() { // Being settable is a super set of being addressable.
|
||||
return fmt.Errorf("cannot decode element '%s' into field %v; it is not settable", name, field)
|
||||
}
|
||||
if field.Kind() == reflect.Ptr && field.IsNil() {
|
||||
field.Set(reflect.New(field.Type().Elem()))
|
||||
}
|
||||
field = field.Addr()
|
||||
|
||||
dctx := DecodeContext{Registry: r.Registry, Truncate: fd.truncate}
|
||||
if fd.decoder == nil {
|
||||
return ErrNoDecoder{Type: field.Elem().Type()}
|
||||
}
|
||||
|
||||
if decoder, ok := fd.decoder.(ValueDecoder); ok {
|
||||
err = decoder.DecodeValue(dctx, vr, field.Elem())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
err = fd.decoder.DecodeValue(dctx, vr, field)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sc *StructCodec) isZero(i interface{}) bool {
|
||||
v := reflect.ValueOf(i)
|
||||
|
||||
// check the value validity
|
||||
if !v.IsValid() {
|
||||
return true
|
||||
}
|
||||
|
||||
if z, ok := v.Interface().(Zeroer); ok && (v.Kind() != reflect.Ptr || !v.IsNil()) {
|
||||
return z.IsZero()
|
||||
}
|
||||
|
||||
switch v.Kind() {
|
||||
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
|
||||
return v.Len() == 0
|
||||
case reflect.Bool:
|
||||
return !v.Bool()
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return v.Int() == 0
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
return v.Uint() == 0
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return v.Float() == 0
|
||||
case reflect.Interface, reflect.Ptr:
|
||||
return v.IsNil()
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
type structDescription struct {
|
||||
fm map[string]fieldDescription
|
||||
fl []fieldDescription
|
||||
inlineMap int
|
||||
}
|
||||
|
||||
type fieldDescription struct {
|
||||
name string
|
||||
idx int
|
||||
omitEmpty bool
|
||||
minSize bool
|
||||
truncate bool
|
||||
inline []int
|
||||
encoder ValueEncoder
|
||||
decoder ValueDecoder
|
||||
}
|
||||
|
||||
func (sc *StructCodec) describeStruct(r *Registry, t reflect.Type) (*structDescription, error) {
|
||||
// We need to analyze the struct, including getting the tags, collecting
|
||||
// information about inlining, and create a map of the field name to the field.
|
||||
sc.l.RLock()
|
||||
ds, exists := sc.cache[t]
|
||||
sc.l.RUnlock()
|
||||
if exists {
|
||||
return ds, nil
|
||||
}
|
||||
|
||||
numFields := t.NumField()
|
||||
sd := &structDescription{
|
||||
fm: make(map[string]fieldDescription, numFields),
|
||||
fl: make([]fieldDescription, 0, numFields),
|
||||
inlineMap: -1,
|
||||
}
|
||||
|
||||
for i := 0; i < numFields; i++ {
|
||||
sf := t.Field(i)
|
||||
if sf.PkgPath != "" {
|
||||
// unexported, ignore
|
||||
continue
|
||||
}
|
||||
|
||||
encoder, err := r.LookupEncoder(sf.Type)
|
||||
if err != nil {
|
||||
encoder = nil
|
||||
}
|
||||
decoder, err := r.LookupDecoder(sf.Type)
|
||||
if err != nil {
|
||||
decoder = nil
|
||||
}
|
||||
|
||||
description := fieldDescription{idx: i, encoder: encoder, decoder: decoder}
|
||||
|
||||
stags, err := sc.parser.ParseStructTags(sf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if stags.Skip {
|
||||
continue
|
||||
}
|
||||
description.name = stags.Name
|
||||
description.omitEmpty = stags.OmitEmpty
|
||||
description.minSize = stags.MinSize
|
||||
description.truncate = stags.Truncate
|
||||
|
||||
if stags.Inline {
|
||||
switch sf.Type.Kind() {
|
||||
case reflect.Map:
|
||||
if sd.inlineMap >= 0 {
|
||||
return nil, errors.New("(struct " + t.String() + ") multiple inline maps")
|
||||
}
|
||||
if sf.Type.Key() != tString {
|
||||
return nil, errors.New("(struct " + t.String() + ") inline map must have a string keys")
|
||||
}
|
||||
sd.inlineMap = description.idx
|
||||
case reflect.Struct:
|
||||
inlinesf, err := sc.describeStruct(r, sf.Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, fd := range inlinesf.fl {
|
||||
if _, exists := sd.fm[fd.name]; exists {
|
||||
return nil, fmt.Errorf("(struct %s) duplicated key %s", t.String(), fd.name)
|
||||
}
|
||||
if fd.inline == nil {
|
||||
fd.inline = []int{i, fd.idx}
|
||||
} else {
|
||||
fd.inline = append([]int{i}, fd.inline...)
|
||||
}
|
||||
sd.fm[fd.name] = fd
|
||||
sd.fl = append(sd.fl, fd)
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("(struct %s) inline fields must be either a struct or a map", t.String())
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if _, exists := sd.fm[description.name]; exists {
|
||||
return nil, fmt.Errorf("struct %s) duplicated key %s", t.String(), description.name)
|
||||
}
|
||||
|
||||
sd.fm[description.name] = description
|
||||
sd.fl = append(sd.fl, description)
|
||||
}
|
||||
|
||||
sc.l.Lock()
|
||||
sc.cache[t] = sd
|
||||
sc.l.Unlock()
|
||||
|
||||
return sd, nil
|
||||
}
|
119
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_tag_parser.go
generated
vendored
Normal file
119
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_tag_parser.go
generated
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
// Copyright (C) MongoDB, Inc. 2017-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package bsoncodec
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// StructTagParser returns the struct tags for a given struct field.
|
||||
type StructTagParser interface {
|
||||
ParseStructTags(reflect.StructField) (StructTags, error)
|
||||
}
|
||||
|
||||
// StructTagParserFunc is an adapter that allows a generic function to be used
|
||||
// as a StructTagParser.
|
||||
type StructTagParserFunc func(reflect.StructField) (StructTags, error)
|
||||
|
||||
// ParseStructTags implements the StructTagParser interface.
|
||||
func (stpf StructTagParserFunc) ParseStructTags(sf reflect.StructField) (StructTags, error) {
|
||||
return stpf(sf)
|
||||
}
|
||||
|
||||
// StructTags represents the struct tag fields that the StructCodec uses during
|
||||
// the encoding and decoding process.
|
||||
//
|
||||
// In the case of a struct, the lowercased field name is used as the key for each exported
|
||||
// field but this behavior may be changed using a struct tag. The tag may also contain flags to
|
||||
// adjust the marshalling behavior for the field.
|
||||
//
|
||||
// The properties are defined below:
|
||||
//
|
||||
// OmitEmpty Only include the field if it's not set to the zero value for the type or to
|
||||
// empty slices or maps.
|
||||
//
|
||||
// MinSize Marshal an integer of a type larger than 32 bits value as an int32, if that's
|
||||
// feasible while preserving the numeric value.
|
||||
//
|
||||
// Truncate When unmarshaling a BSON double, it is permitted to lose precision to fit within
|
||||
// a float32.
|
||||
//
|
||||
// Inline Inline the field, which must be a struct or a map, causing all of its fields
|
||||
// or keys to be processed as if they were part of the outer struct. For maps,
|
||||
// keys must not conflict with the bson keys of other struct fields.
|
||||
//
|
||||
// Skip This struct field should be skipped. This is usually denoted by parsing a "-"
|
||||
// for the name.
|
||||
//
|
||||
// TODO(skriptble): Add tags for undefined as nil and for null as nil.
|
||||
type StructTags struct {
|
||||
Name string
|
||||
OmitEmpty bool
|
||||
MinSize bool
|
||||
Truncate bool
|
||||
Inline bool
|
||||
Skip bool
|
||||
}
|
||||
|
||||
// DefaultStructTagParser is the StructTagParser used by the StructCodec by default.
|
||||
// It will handle the bson struct tag. See the documentation for StructTags to see
|
||||
// what each of the returned fields means.
|
||||
//
|
||||
// If there is no name in the struct tag fields, the struct field name is lowercased.
|
||||
// The tag formats accepted are:
|
||||
//
|
||||
// "[<key>][,<flag1>[,<flag2>]]"
|
||||
//
|
||||
// `(...) bson:"[<key>][,<flag1>[,<flag2>]]" (...)`
|
||||
//
|
||||
// An example:
|
||||
//
|
||||
// type T struct {
|
||||
// A bool
|
||||
// B int "myb"
|
||||
// C string "myc,omitempty"
|
||||
// D string `bson:",omitempty" json:"jsonkey"`
|
||||
// E int64 ",minsize"
|
||||
// F int64 "myf,omitempty,minsize"
|
||||
// }
|
||||
//
|
||||
// A struct tag either consisting entirely of '-' or with a bson key with a
|
||||
// value consisting entirely of '-' will return a StructTags with Skip true and
|
||||
// the remaining fields will be their default values.
|
||||
var DefaultStructTagParser StructTagParserFunc = func(sf reflect.StructField) (StructTags, error) {
|
||||
key := strings.ToLower(sf.Name)
|
||||
tag, ok := sf.Tag.Lookup("bson")
|
||||
if !ok && !strings.Contains(string(sf.Tag), ":") && len(sf.Tag) > 0 {
|
||||
tag = string(sf.Tag)
|
||||
}
|
||||
var st StructTags
|
||||
if tag == "-" {
|
||||
st.Skip = true
|
||||
return st, nil
|
||||
}
|
||||
|
||||
for idx, str := range strings.Split(tag, ",") {
|
||||
if idx == 0 && str != "" {
|
||||
key = str
|
||||
}
|
||||
switch str {
|
||||
case "omitempty":
|
||||
st.OmitEmpty = true
|
||||
case "minsize":
|
||||
st.MinSize = true
|
||||
case "truncate":
|
||||
st.Truncate = true
|
||||
case "inline":
|
||||
st.Inline = true
|
||||
}
|
||||
}
|
||||
|
||||
st.Name = key
|
||||
|
||||
return st, nil
|
||||
}
|
80
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/types.go
generated
vendored
Normal file
80
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/types.go
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
// Copyright (C) MongoDB, Inc. 2017-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package bsoncodec
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
|
||||
)
|
||||
|
||||
var ptBool = reflect.TypeOf((*bool)(nil))
|
||||
var ptInt8 = reflect.TypeOf((*int8)(nil))
|
||||
var ptInt16 = reflect.TypeOf((*int16)(nil))
|
||||
var ptInt32 = reflect.TypeOf((*int32)(nil))
|
||||
var ptInt64 = reflect.TypeOf((*int64)(nil))
|
||||
var ptInt = reflect.TypeOf((*int)(nil))
|
||||
var ptUint8 = reflect.TypeOf((*uint8)(nil))
|
||||
var ptUint16 = reflect.TypeOf((*uint16)(nil))
|
||||
var ptUint32 = reflect.TypeOf((*uint32)(nil))
|
||||
var ptUint64 = reflect.TypeOf((*uint64)(nil))
|
||||
var ptUint = reflect.TypeOf((*uint)(nil))
|
||||
var ptFloat32 = reflect.TypeOf((*float32)(nil))
|
||||
var ptFloat64 = reflect.TypeOf((*float64)(nil))
|
||||
var ptString = reflect.TypeOf((*string)(nil))
|
||||
|
||||
var tBool = reflect.TypeOf(false)
|
||||
var tFloat32 = reflect.TypeOf(float32(0))
|
||||
var tFloat64 = reflect.TypeOf(float64(0))
|
||||
var tInt = reflect.TypeOf(int(0))
|
||||
var tInt8 = reflect.TypeOf(int8(0))
|
||||
var tInt16 = reflect.TypeOf(int16(0))
|
||||
var tInt32 = reflect.TypeOf(int32(0))
|
||||
var tInt64 = reflect.TypeOf(int64(0))
|
||||
var tString = reflect.TypeOf("")
|
||||
var tTime = reflect.TypeOf(time.Time{})
|
||||
var tUint = reflect.TypeOf(uint(0))
|
||||
var tUint8 = reflect.TypeOf(uint8(0))
|
||||
var tUint16 = reflect.TypeOf(uint16(0))
|
||||
var tUint32 = reflect.TypeOf(uint32(0))
|
||||
var tUint64 = reflect.TypeOf(uint64(0))
|
||||
|
||||
var tEmpty = reflect.TypeOf((*interface{})(nil)).Elem()
|
||||
var tByteSlice = reflect.TypeOf([]byte(nil))
|
||||
var tByte = reflect.TypeOf(byte(0x00))
|
||||
var tURL = reflect.TypeOf(url.URL{})
|
||||
var tJSONNumber = reflect.TypeOf(json.Number(""))
|
||||
|
||||
var tValueMarshaler = reflect.TypeOf((*ValueMarshaler)(nil)).Elem()
|
||||
var tValueUnmarshaler = reflect.TypeOf((*ValueUnmarshaler)(nil)).Elem()
|
||||
var tMarshaler = reflect.TypeOf((*Marshaler)(nil)).Elem()
|
||||
var tUnmarshaler = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
|
||||
var tProxy = reflect.TypeOf((*Proxy)(nil)).Elem()
|
||||
|
||||
var tBinary = reflect.TypeOf(primitive.Binary{})
|
||||
var tUndefined = reflect.TypeOf(primitive.Undefined{})
|
||||
var tOID = reflect.TypeOf(primitive.ObjectID{})
|
||||
var tDateTime = reflect.TypeOf(primitive.DateTime(0))
|
||||
var tNull = reflect.TypeOf(primitive.Null{})
|
||||
var tRegex = reflect.TypeOf(primitive.Regex{})
|
||||
var tCodeWithScope = reflect.TypeOf(primitive.CodeWithScope{})
|
||||
var tDBPointer = reflect.TypeOf(primitive.DBPointer{})
|
||||
var tJavaScript = reflect.TypeOf(primitive.JavaScript(""))
|
||||
var tSymbol = reflect.TypeOf(primitive.Symbol(""))
|
||||
var tTimestamp = reflect.TypeOf(primitive.Timestamp{})
|
||||
var tDecimal = reflect.TypeOf(primitive.Decimal128{})
|
||||
var tMinKey = reflect.TypeOf(primitive.MinKey{})
|
||||
var tMaxKey = reflect.TypeOf(primitive.MaxKey{})
|
||||
var tD = reflect.TypeOf(primitive.D{})
|
||||
var tA = reflect.TypeOf(primitive.A{})
|
||||
var tE = reflect.TypeOf(primitive.E{})
|
||||
|
||||
var tCoreDocument = reflect.TypeOf(bsoncore.Document{})
|
Reference in New Issue
Block a user