// TODO : Can be made much more generic with the help of reflection (but has some golang limitations)
549455
func (n *network) UnmarshalJSON(b []byte) (err error) {
	var netMap map[string]interface{}
	if err := json.Unmarshal(b, &netMap); err != nil {
		return err
	}
	n.name = netMap["name"].(string)
	n.id = netMap["id"].(string)
	// "created" is not available in older versions
	if v, ok := netMap["created"]; ok {
		// n.created is time.Time but marshalled as string
		if err = n.created.UnmarshalText([]byte(v.(string))); err != nil {
			logrus.Warnf("failed to unmarshal creation time %v: %v", v, err)
			n.created = time.Time{}
		}
	}
	n.networkType = netMap["networkType"].(string)
	n.enableIPv6 = netMap["enableIPv6"].(bool)

	// if we weren't unmarshaling to netMap we could simply set n.labels
	// unfortunately, we can't because map[string]interface{} != map[string]string
	if labels, ok := netMap["labels"].(map[string]interface{}); ok {
		n.labels = make(map[string]string, len(labels))
		for label, value := range labels {
			n.labels[label] = value.(string)
		}
	}

	if v, ok := netMap["ipamOptions"]; ok {
		if iOpts, ok := v.(map[string]interface{}); ok {
			n.ipamOptions = make(map[string]string, len(iOpts))
			for k, v := range iOpts {
				n.ipamOptions[k] = v.(string)
			}
		}
	}

	if v, ok := netMap["generic"]; ok {
		n.generic = v.(map[string]interface{})
		// Restore opts in their map[string]string form
		if v, ok := n.generic[netlabel.GenericData]; ok {
			var lmap map[string]string
			ba, err := json.Marshal(v)
			if err != nil {
				return err
			}
			if err := json.Unmarshal(ba, &lmap); err != nil {
				return err
			}
			n.generic[netlabel.GenericData] = lmap
		}
	}
	if v, ok := netMap["persist"]; ok {
		n.persist = v.(bool)
	}
	if v, ok := netMap["postIPv6"]; ok {
		n.postIPv6 = v.(bool)
	}
	if v, ok := netMap["ipamType"]; ok {
		n.ipamType = v.(string)
	} else {
		n.ipamType = ipamapi.DefaultIPAM
	}
	if v, ok := netMap["addrSpace"]; ok {
		n.addrSpace = v.(string)
	}
	if v, ok := netMap["ipamV4Config"]; ok {
		if err := json.Unmarshal([]byte(v.(string)), &n.ipamV4Config); err != nil {
			return err
		}
	}
	if v, ok := netMap["ipamV4Info"]; ok {
		if err := json.Unmarshal([]byte(v.(string)), &n.ipamV4Info); err != nil {
			return err
		}
	}
	if v, ok := netMap["ipamV6Config"]; ok {
		if err := json.Unmarshal([]byte(v.(string)), &n.ipamV6Config); err != nil {
			return err
		}
	}
	if v, ok := netMap["ipamV6Info"]; ok {
		if err := json.Unmarshal([]byte(v.(string)), &n.ipamV6Info); err != nil {
			return err
		}
	}
	if v, ok := netMap["internal"]; ok {
		n.internal = v.(bool)
	}
	if v, ok := netMap["attachable"]; ok {
		n.attachable = v.(bool)
	}
	if s, ok := netMap["scope"]; ok {
		n.scope = s.(string)
	}
	if v, ok := netMap["inDelete"]; ok {
		n.inDelete = v.(bool)
	}
	if v, ok := netMap["ingress"]; ok {
		n.ingress = v.(bool)
	}
	if v, ok := netMap["configOnly"]; ok {
		n.configOnly = v.(bool)
	}
	if v, ok := netMap["configFrom"]; ok {
		n.configFrom = v.(string)
	}
	if v, ok := netMap["loadBalancerIP"]; ok {
		n.loadBalancerIP = net.ParseIP(v.(string))
	}
	n.loadBalancerMode = loadBalancerModeDefault
	if v, ok := netMap["loadBalancerMode"]; ok {
		n.loadBalancerMode = v.(string)
	}
	// Reconcile old networks with the recently added `--ipv6` flag
	if !n.enableIPv6 {
		n.enableIPv6 = len(n.ipamV6Info) > 0
	}
	return nil
}
1311329
func structToMap(v reflect.Value) map[string]interface{} {
	out := make(map[string]interface{})
	t := v.Type()
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)
		if field.PkgPath != "" {
			// unexported field. skip.
			continue
		}
		out[field.Name] = v.FieldByName(field.Name).Interface()
	}
	return out
}
1214672
func typeOf(i interface{}) string {
	if i == nil {
		return ""
	}
	return reflect.TypeOf(i).Elem().Name()
}
561732
func newGenericFunc(methodName, paramName string, fn interface{}, validateFunc func(*functionCache) error) (*genericFunc, error) {
	cache := &functionCache{}
	cache.FnValue = reflect.ValueOf(fn)

	if cache.FnValue.Kind() != reflect.Func {
		return nil, fmt.Errorf("%s: parameter [%s] is not a function type. It is a '%s'", methodName, paramName, cache.FnValue.Type())
	}
	cache.MethodName = methodName
	cache.ParamName = paramName
	cache.FnType = cache.FnValue.Type()
	numTypesIn := cache.FnType.NumIn()
	cache.TypesIn = make([]reflect.Type, numTypesIn)
	for i := 0; i < numTypesIn; i++ {
		cache.TypesIn[i] = cache.FnType.In(i)
	}

	numTypesOut := cache.FnType.NumOut()
	cache.TypesOut = make([]reflect.Type, numTypesOut)
	for i := 0; i < numTypesOut; i++ {
		cache.TypesOut[i] = cache.FnType.Out(i)
	}
	if err := validateFunc(cache); err != nil {
		return nil, err
	}

	return &genericFunc{Cache: cache}, nil
}
851562
func getLess(t reflect.Type) (f func(x, y interface{}) bool) {
	switch t.Kind() {
	case reflect.Bool:
		f = func(x, y interface{}) bool { return !x.(bool) && y.(bool) }
	case reflect.Int:
		f = func(x, y interface{}) bool { return x.(int) < y.(int) }
	case reflect.Int8:
		f = func(x, y interface{}) bool { return x.(int8) < y.(int8) }
	case reflect.Int16:
		f = func(x, y interface{}) bool { return x.(int16) < y.(int16) }
	case reflect.Int32:
		f = func(x, y interface{}) bool { return x.(int32) < y.(int32) }
	case reflect.Int64:
		f = func(x, y interface{}) bool { return x.(int64) < y.(int64) }
	case reflect.Uint:
		f = func(x, y interface{}) bool { return x.(uint) < y.(uint) }
	case reflect.Uint8:
		f = func(x, y interface{}) bool { return x.(uint8) < y.(uint8) }
	case reflect.Uint16:
		f = func(x, y interface{}) bool { return x.(uint16) < y.(uint16) }
	case reflect.Uint32:
		f = func(x, y interface{}) bool { return x.(uint32) < y.(uint32) }
	case reflect.Uint64:
		f = func(x, y interface{}) bool { return x.(uint64) < y.(uint64) }
	case reflect.Float32:
		f = func(x, y interface{}) bool { return x.(float32) < y.(float32) }
	case reflect.Float64:
		f = func(x, y interface{}) bool { return x.(float64) < y.(float64) }
	case reflect.String:
		f = func(x, y interface{}) bool { return x.(string) < y.(string) }
	case reflect.TypeOf(time.Time{}).Kind():
		f = func(x, y interface{}) bool { return x.(time.Time).Before(y.(time.Time)) }
	default:
		panic(fmt.Sprintf("sortmap: unsupported type: %s", t))
	}
	return
}
1036770
func (t *ObjType) Method(name string) (ObjMethod, error) {
	m, ok := t.method[name]
	if !ok {
		return ObjMethod{}, ErrMethodNotFound
	}
	return *m, nil
}
339545
func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) {
	p.init(typ, name, tag, f, true)
}
568837
func ReflectStruct(dest interface{}, src interface{}) (err error) {
	if dest == nil || src == nil {
		return
	}

	return reflectField(
		reflect.ValueOf(dest),
		reflect.ValueOf(src),
	)
}
466598
func (self *_runtime) convertCallParameter(v Value, t reflect.Type) reflect.Value {
	if t == typeOfValue {
		return reflect.ValueOf(v)
	}

	if v.kind == valueObject {
		if gso, ok := v._object().value.(*_goStructObject); ok {
			if gso.value.Type().AssignableTo(t) {
				// please see TestDynamicFunctionReturningInterface for why this exists
				if t.Kind() == reflect.Interface && gso.value.Type().ConvertibleTo(t) {
					return gso.value.Convert(t)
				} else {
					return gso.value
				}
			}
		}

		if gao, ok := v._object().value.(*_goArrayObject); ok {
			if gao.value.Type().AssignableTo(t) {
				// please see TestDynamicFunctionReturningInterface for why this exists
				if t.Kind() == reflect.Interface && gao.value.Type().ConvertibleTo(t) {
					return gao.value.Convert(t)
				} else {
					return gao.value
				}
			}
		}
	}

	if t.Kind() == reflect.Interface {
		e := v.export()
		if e == nil {
			return reflect.Zero(t)
		}
		iv := reflect.ValueOf(e)
		if iv.Type().AssignableTo(t) {
			return iv
		}
	}

	tk := t.Kind()

	if tk == reflect.Ptr {
		switch v.kind {
		case valueEmpty, valueNull, valueUndefined:
			return reflect.Zero(t)
		default:
			var vv reflect.Value
			if err := catchPanic(func() { vv = self.convertCallParameter(v, t.Elem()) }); err == nil {
				if vv.CanAddr() {
					return vv.Addr()
				}

				pv := reflect.New(vv.Type())
				pv.Elem().Set(vv)
				return pv
			}
		}
	}

	switch tk {
	case reflect.Bool:
		return reflect.ValueOf(v.bool())
	case reflect.String:
		switch v.kind {
		case valueString:
			return reflect.ValueOf(v.value)
		case valueNumber:
			return reflect.ValueOf(fmt.Sprintf("%v", v.value))
		}
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64:
		switch v.kind {
		case valueNumber:
			return self.convertNumeric(v, t)
		}
	case reflect.Slice:
		if o := v._object(); o != nil {
			if lv := o.get("length"); lv.IsNumber() {
				l := lv.number().int64

				s := reflect.MakeSlice(t, int(l), int(l))

				tt := t.Elem()

				if o.class == "Array" {
					for i := int64(0); i < l; i++ {
						p, ok := o.property[strconv.FormatInt(i, 10)]
						if !ok {
							continue
						}

						e, ok := p.value.(Value)
						if !ok {
							continue
						}

						ev := self.convertCallParameter(e, tt)

						s.Index(int(i)).Set(ev)
					}
				} else if o.class == "GoArray" {

					var gslice bool
					switch o.value.(type) {
					case *_goSliceObject:
						gslice = true
					case *_goArrayObject:
						gslice = false
					}

					for i := int64(0); i < l; i++ {
						var p *_property
						if gslice {
							p = goSliceGetOwnProperty(o, strconv.FormatInt(i, 10))
						} else {
							p = goArrayGetOwnProperty(o, strconv.FormatInt(i, 10))
						}
						if p == nil {
							continue
						}

						e, ok := p.value.(Value)
						if !ok {
							continue
						}

						ev := self.convertCallParameter(e, tt)

						s.Index(int(i)).Set(ev)
					}
				}

				return s
			}
		}
	case reflect.Map:
		if o := v._object(); o != nil && t.Key().Kind() == reflect.String {
			m := reflect.MakeMap(t)

			o.enumerate(false, func(k string) bool {
				m.SetMapIndex(reflect.ValueOf(k), self.convertCallParameter(o.get(k), t.Elem()))
				return true
			})

			return m
		}
	case reflect.Func:
		if t.NumOut() > 1 {
			panic(self.panicTypeError("converting JavaScript values to Go functions with more than one return value is currently not supported"))
		}

		if o := v._object(); o != nil && o.class == "Function" {
			return reflect.MakeFunc(t, func(args []reflect.Value) []reflect.Value {
				l := make([]interface{}, len(args))
				for i, a := range args {
					if a.CanInterface() {
						l[i] = a.Interface()
					}
				}

				rv, err := v.Call(nullValue, l...)
				if err != nil {
					panic(err)
				}

				if t.NumOut() == 0 {
					return nil
				}

				return []reflect.Value{self.convertCallParameter(rv, t.Out(0))}
			})
		}
	case reflect.Struct:
		if o := v._object(); o != nil && o.class == "Object" {
			s := reflect.New(t)

			for _, k := range o.propertyOrder {
				var f *reflect.StructField

				for i := 0; i < t.NumField(); i++ {
					ff := t.Field(i)

					if j := ff.Tag.Get("json"); j != "" {
						if j == "-" {
							continue
						}

						a := strings.Split(j, ",")

						if a[0] == k {
							f = &ff
							break
						}
					}

					if ff.Name == k {
						f = &ff
						break
					}

					if strings.EqualFold(ff.Name, k) {
						f = &ff
					}
				}

				if f == nil {
					panic(self.panicTypeError("can't convert object; field %q was supplied but does not exist on target %v", k, t))
				}

				ss := s

				for _, i := range f.Index {
					if ss.Kind() == reflect.Ptr {
						if ss.IsNil() {
							if !ss.CanSet() {
								panic(self.panicTypeError("can't set embedded pointer to unexported struct: %v", ss.Type().Elem()))
							}

							ss.Set(reflect.New(ss.Type().Elem()))
						}

						ss = ss.Elem()
					}

					ss = ss.Field(i)
				}

				ss.Set(self.convertCallParameter(o.get(k), ss.Type()))
			}

			return s.Elem()
		}
	}

	if tk == reflect.String {
		if o := v._object(); o != nil && o.hasProperty("toString") {
			if fn := o.get("toString"); fn.IsFunction() {
				sv, err := fn.Call(v)
				if err != nil {
					panic(err)
				}

				var r reflect.Value
				if err := catchPanic(func() { r = self.convertCallParameter(sv, t) }); err == nil {
					return r
				}
			}
		}

		return reflect.ValueOf(v.String())
	}

	if v.kind == valueString {
		var s encoding.TextUnmarshaler

		if reflect.PtrTo(t).Implements(reflect.TypeOf(&s).Elem()) {
			r := reflect.New(t)

			if err := r.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(v.string())); err != nil {
				panic(self.panicSyntaxError("can't convert to %s: %s", t.String(), err.Error()))
			}

			return r.Elem()
		}
	}

	s := "OTTO DOES NOT UNDERSTAND THIS TYPE"
	switch v.kind {
	case valueBoolean:
		s = "boolean"
	case valueNull:
		s = "null"
	case valueNumber:
		s = "number"
	case valueString:
		s = "string"
	case valueUndefined:
		s = "undefined"
	case valueObject:
		s = v.Class()
	}

	panic(self.panicTypeError("can't convert from %q to %q", s, t.String()))
}
281313
func (s *Section) ReflectFrom(v interface{}) error {
	typ := reflect.TypeOf(v)
	val := reflect.ValueOf(v)
	if typ.Kind() == reflect.Ptr {
		typ = typ.Elem()
		val = val.Elem()
	} else {
		return errors.New("cannot reflect from non-pointer struct")
	}

	return s.reflectFrom(val)
}
121036
func ReflectRecursive(v reflect.Value, visitor visitorFunc) error {
	return reflectRecursive("", v, visitor)
}
216011
func interfaceOf(v reflect.Value) interface{} {
	if v.Kind() == reflect.Ptr {
		return v.Elem().Interface()
	}

	return v.Interface()
}
609292
func typeOf(goType reflect.Type) *Type {
	rm := &Type{
		method: make(map[string]*RootMethod),
	}
	for i := 0; i < goType.NumMethod(); i++ {
		m := goType.Method(i)
		if m.PkgPath != "" || isKillMethod(m) {
			// The Kill method gets a special exception because
			// it fulfils the Killer interface which we're expecting,
			// so it's not really discarded as such.
			continue
		}
		if o := newRootMethod(m); o != nil {
			rm.method[m.Name] = o
		} else {
			rm.discarded = append(rm.discarded, m.Name)
		}
	}
	return rm
}
1011924
func convert(t reflect.Type, value string) (reflect.Value, error) {
	if value == "" {
		return reflect.ValueOf(nil), nil
	}

	switch t.Kind() {
	case reflect.String:
		return reflect.ValueOf(value), nil
		// ptr.Elem()
		// ptr = reflect.ValueOf(value).Elem().Convert(reflect.String)
		// return reflect.ValueOf(value), nil
	case reflect.Int:
		return parseInt(value)
	case reflect.Bool:

		return parseBool(value)
	}

	return reflect.ValueOf(nil), conversionError(value, `unsupported `+t.Kind().String())
}
326856
func interfaceToStringMap(obj interface{}) (map[string]string, bool) {
	if obj == nil {
		return nil, false
	}
	lm, ok := obj.(map[string]interface{})
	if !ok {
		return nil, false
	}
	existing := make(map[string]string)
	for k, v := range lm {
		switch t := v.(type) {
		case string:
			existing[k] = t
		}
	}
	return existing, true
}
422257
func (m *GenericParser) parseLit(val reflect.Value) (Object, error) {
	switch k := val.Kind(); k {
	case reflect.Bool:
		return B(val.Bool()), nil
	case reflect.Int:
		return I(val.Int()), nil
	case reflect.Int8:
		return I8(val.Int()), nil
	case reflect.Int16:
		return I16(val.Int()), nil
	case reflect.Int32:
		return I32(val.Int()), nil
	case reflect.Int64:
		return I64(val.Int()), nil
	case reflect.Uint:
		return U(val.Uint()), nil
	case reflect.Uint8:
		return U8(val.Uint()), nil
	case reflect.Uint16:
		return U16(val.Uint()), nil
	case reflect.Uint32:
		return U32(val.Uint()), nil
	case reflect.Uint64:
		return U64(val.Uint()), nil
	case reflect.Float32:
		return F32(val.Float()), nil
	case reflect.Float64:
		return F64(val.Float()), nil
	case reflect.Complex64:
		m.Stats.Count("parser.parseLit."+k.String(), 1, 1)
		return nil, errors.New("unsupported kind of literal Complex64")
	case reflect.Complex128:
		m.Stats.Count("parser.parseLit."+k.String(), 1, 1)
		return nil, errors.New("unsupported kind of literal Complex128")
	case reflect.Array, reflect.Slice:
		m.Stats.Count("parser.parseLit."+k.String(), 1, 1)
		return nil, errors.New("nested slices/arrays of literals are not supported - parseLit should not be called with these kinds of values")
	case reflect.String:
		return S(val.String()), nil
	default:
		m.Stats.Count("parser.parseLit."+k.String(), 1, 1)
		return nil, errors.Errorf("kind %v is not supported", val.Kind())
	}
}
96335
func LookupPatchMetadata(t reflect.Type, jsonField string) (reflect.Type, string, string, error) {
	if t.Kind() == reflect.Map {
		return t.Elem(), "", "", nil
	}
	if t.Kind() != reflect.Struct {
		return nil, "", "", fmt.Errorf("merging an object in json but data type is not map or struct, instead is: %s",
			t.Kind().String())
	}
	jf := []byte(jsonField)
	// Find the field that the JSON library would use.
	var f *field
	fields := cachedTypeFields(t)
	for i := range fields {
		ff := &fields[i]
		if bytes.Equal(ff.nameBytes, jf) {
			f = ff
			break
		}
		// Do case-insensitive comparison.
		if f == nil && ff.equalFold(ff.nameBytes, jf) {
			f = ff
		}
	}
	if f != nil {
		// Find the reflect.Value of the most preferential struct field.
		tjf := t.Field(f.index[0])
		// we must navigate down all the anonymously included structs in the chain
		for i := 1; i < len(f.index); i++ {
			tjf = tjf.Type.Field(f.index[i])
		}
		patchStrategy := tjf.Tag.Get("patchStrategy")
		patchMergeKey := tjf.Tag.Get("patchMergeKey")
		return tjf.Type, patchStrategy, patchMergeKey, nil
	}
	return nil, "", "", fmt.Errorf("unable to find api field in struct %s for the json field %q", t.Name(), jsonField)
}