[VOL-3678] First implementation of the BBSim-sadis-server

Change-Id: I5077a8f861f4cc6af9759f31a4a415042c05eba3
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/valuereflect.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/valuereflect.go
new file mode 100644
index 0000000..05e70de
--- /dev/null
+++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/valuereflect.go
@@ -0,0 +1,294 @@
+/*
+Copyright 2019 The Kubernetes Authors.
+
+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
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package value
+
+import (
+	"encoding/base64"
+	"fmt"
+	"reflect"
+)
+
+// NewValueReflect creates a Value backed by an "interface{}" type,
+// typically an structured object in Kubernetes world that is uses reflection to expose.
+// The provided "interface{}" value must be a pointer so that the value can be modified via reflection.
+// The provided "interface{}" may contain structs and types that are converted to Values
+// by the jsonMarshaler interface.
+func NewValueReflect(value interface{}) (Value, error) {
+	if value == nil {
+		return NewValueInterface(nil), nil
+	}
+	v := reflect.ValueOf(value)
+	if v.Kind() != reflect.Ptr {
+		// The root value to reflect on must be a pointer so that map.Set() and map.Delete() operations are possible.
+		return nil, fmt.Errorf("value provided to NewValueReflect must be a pointer")
+	}
+	return wrapValueReflect(v, nil, nil)
+}
+
+// wrapValueReflect wraps the provide reflect.Value as a value. If parent in the data tree is a map, parentMap
+// and parentMapKey must be provided so that the returned value may be set and deleted.
+func wrapValueReflect(value reflect.Value, parentMap, parentMapKey *reflect.Value) (Value, error) {
+	val := HeapAllocator.allocValueReflect()
+	return val.reuse(value, nil, parentMap, parentMapKey)
+}
+
+// wrapValueReflect wraps the provide reflect.Value as a value, and panics if there is an error. If parent in the data
+// tree is a map, parentMap and parentMapKey must be provided so that the returned value may be set and deleted.
+func mustWrapValueReflect(value reflect.Value, parentMap, parentMapKey *reflect.Value) Value {
+	v, err := wrapValueReflect(value, parentMap, parentMapKey)
+	if err != nil {
+		panic(err)
+	}
+	return v
+}
+
+// the value interface doesn't care about the type for value.IsNull, so we can use a constant
+var nilType = reflect.TypeOf(&struct{}{})
+
+// reuse replaces the value of the valueReflect. If parent in the data tree is a map, parentMap and parentMapKey
+// must be provided so that the returned value may be set and deleted.
+func (r *valueReflect) reuse(value reflect.Value, cacheEntry *TypeReflectCacheEntry, parentMap, parentMapKey *reflect.Value) (Value, error) {
+	if cacheEntry == nil {
+		cacheEntry = TypeReflectEntryOf(value.Type())
+	}
+	if cacheEntry.CanConvertToUnstructured() {
+		u, err := cacheEntry.ToUnstructured(value)
+		if err != nil {
+			return nil, err
+		}
+		if u == nil {
+			value = reflect.Zero(nilType)
+		} else {
+			value = reflect.ValueOf(u)
+		}
+	}
+	r.Value = dereference(value)
+	r.ParentMap = parentMap
+	r.ParentMapKey = parentMapKey
+	r.kind = kind(r.Value)
+	return r, nil
+}
+
+// mustReuse replaces the value of the valueReflect and panics if there is an error. If parent in the data tree is a
+// map, parentMap and parentMapKey must be provided so that the returned value may be set and deleted.
+func (r *valueReflect) mustReuse(value reflect.Value, cacheEntry *TypeReflectCacheEntry, parentMap, parentMapKey *reflect.Value) Value {
+	v, err := r.reuse(value, cacheEntry, parentMap, parentMapKey)
+	if err != nil {
+		panic(err)
+	}
+	return v
+}
+
+func dereference(val reflect.Value) reflect.Value {
+	kind := val.Kind()
+	if (kind == reflect.Interface || kind == reflect.Ptr) && !safeIsNil(val) {
+		return val.Elem()
+	}
+	return val
+}
+
+type valueReflect struct {
+	ParentMap    *reflect.Value
+	ParentMapKey *reflect.Value
+	Value        reflect.Value
+	kind         reflectType
+}
+
+func (r valueReflect) IsMap() bool {
+	return r.kind == mapType || r.kind == structMapType
+}
+
+func (r valueReflect) IsList() bool {
+	return r.kind == listType
+}
+
+func (r valueReflect) IsBool() bool {
+	return r.kind == boolType
+}
+
+func (r valueReflect) IsInt() bool {
+	return r.kind == intType || r.kind == uintType
+}
+
+func (r valueReflect) IsFloat() bool {
+	return r.kind == floatType
+}
+
+func (r valueReflect) IsString() bool {
+	return r.kind == stringType || r.kind == byteStringType
+}
+
+func (r valueReflect) IsNull() bool {
+	return r.kind == nullType
+}
+
+type reflectType = int
+
+const (
+	mapType = iota
+	structMapType
+	listType
+	intType
+	uintType
+	floatType
+	stringType
+	byteStringType
+	boolType
+	nullType
+)
+
+func kind(v reflect.Value) reflectType {
+	typ := v.Type()
+	rk := typ.Kind()
+	switch rk {
+	case reflect.Map:
+		if v.IsNil() {
+			return nullType
+		}
+		return mapType
+	case reflect.Struct:
+		return structMapType
+	case reflect.Int, reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8:
+		return intType
+	case reflect.Uint, reflect.Uint32, reflect.Uint16, reflect.Uint8:
+		// Uint64 deliberately excluded, see valueUnstructured.Int.
+		return uintType
+	case reflect.Float64, reflect.Float32:
+		return floatType
+	case reflect.String:
+		return stringType
+	case reflect.Bool:
+		return boolType
+	case reflect.Slice:
+		if v.IsNil() {
+			return nullType
+		}
+		elemKind := typ.Elem().Kind()
+		if elemKind == reflect.Uint8 {
+			return byteStringType
+		}
+		return listType
+	case reflect.Chan, reflect.Func, reflect.Ptr, reflect.UnsafePointer, reflect.Interface:
+		if v.IsNil() {
+			return nullType
+		}
+		panic(fmt.Sprintf("unsupported type: %v", v.Type()))
+	default:
+		panic(fmt.Sprintf("unsupported type: %v", v.Type()))
+	}
+}
+
+// TODO find a cleaner way to avoid panics from reflect.IsNil()
+func safeIsNil(v reflect.Value) bool {
+	k := v.Kind()
+	switch k {
+	case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.UnsafePointer, reflect.Interface, reflect.Slice:
+		return v.IsNil()
+	}
+	return false
+}
+
+func (r valueReflect) AsMap() Map {
+	return r.AsMapUsing(HeapAllocator)
+}
+
+func (r valueReflect) AsMapUsing(a Allocator) Map {
+	switch r.kind {
+	case structMapType:
+		v := a.allocStructReflect()
+		v.valueReflect = r
+		return v
+	case mapType:
+		v := a.allocMapReflect()
+		v.valueReflect = r
+		return v
+	default:
+		panic("value is not a map or struct")
+	}
+}
+
+func (r valueReflect) AsList() List {
+	return r.AsListUsing(HeapAllocator)
+}
+
+func (r valueReflect) AsListUsing(a Allocator) List {
+	if r.IsList() {
+		v := a.allocListReflect()
+		v.Value = r.Value
+		return v
+	}
+	panic("value is not a list")
+}
+
+func (r valueReflect) AsBool() bool {
+	if r.IsBool() {
+		return r.Value.Bool()
+	}
+	panic("value is not a bool")
+}
+
+func (r valueReflect) AsInt() int64 {
+	if r.kind == intType {
+		return r.Value.Int()
+	}
+	if r.kind == uintType {
+		return int64(r.Value.Uint())
+	}
+
+	panic("value is not an int")
+}
+
+func (r valueReflect) AsFloat() float64 {
+	if r.IsFloat() {
+		return r.Value.Float()
+	}
+	panic("value is not a float")
+}
+
+func (r valueReflect) AsString() string {
+	switch r.kind {
+	case stringType:
+		return r.Value.String()
+	case byteStringType:
+		return base64.StdEncoding.EncodeToString(r.Value.Bytes())
+	}
+	panic("value is not a string")
+}
+
+func (r valueReflect) Unstructured() interface{} {
+	val := r.Value
+	switch {
+	case r.IsNull():
+		return nil
+	case val.Kind() == reflect.Struct:
+		return structReflect{r}.Unstructured()
+	case val.Kind() == reflect.Map:
+		return mapReflect{valueReflect: r}.Unstructured()
+	case r.IsList():
+		return listReflect{r.Value}.Unstructured()
+	case r.IsString():
+		return r.AsString()
+	case r.IsInt():
+		return r.AsInt()
+	case r.IsBool():
+		return r.AsBool()
+	case r.IsFloat():
+		return r.AsFloat()
+	default:
+		panic(fmt.Sprintf("value of type %s is not a supported by value reflector", val.Type()))
+	}
+}