in filter/generic/generalizer/map.go [88:167]
func objToMap(obj any) any {
if obj == nil {
return obj
}
t := reflect.TypeOf(obj)
v := reflect.ValueOf(obj)
// if obj is a POJO, get the struct from the pointer (if it is a pointer)
pojo, isPojo := obj.(hessian.POJO)
if isPojo {
for t.Kind() == reflect.Ptr {
t = t.Elem()
v = v.Elem()
}
}
switch t.Kind() {
case reflect.Struct:
result := make(map[string]any, t.NumField())
if isPojo {
result["class"] = pojo.JavaClassName()
}
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
value := v.Field(i)
kind := value.Kind()
if !value.CanInterface() {
logger.Debugf("objToMap for %v is skipped because it couldn't be converted to interface", field)
continue
}
valueIface := value.Interface()
switch kind {
case reflect.Ptr:
if value.IsNil() {
setInMap(result, field, nil)
continue
}
setInMap(result, field, objToMap(valueIface))
case reflect.Struct, reflect.Slice, reflect.Map:
if isPrimitive(valueIface) {
logger.Warnf("\"%s\" is primitive. The application may crash if it's transferred between "+
"systems implemented by different languages, e.g. dubbo-go <-> dubbo-java. We recommend "+
"you represent the object by basic types, like string.", value.Type())
setInMap(result, field, valueIface)
continue
}
setInMap(result, field, objToMap(valueIface))
default:
setInMap(result, field, valueIface)
}
}
return result
case reflect.Array, reflect.Slice:
value := reflect.ValueOf(obj)
newTemps := make([]any, 0, value.Len())
for i := 0; i < value.Len(); i++ {
newTemp := objToMap(value.Index(i).Interface())
newTemps = append(newTemps, newTemp)
}
return newTemps
case reflect.Map:
newTempMap := make(map[any]any, v.Len())
iter := v.MapRange()
for iter.Next() {
if !iter.Value().CanInterface() {
continue
}
key := iter.Key()
mapV := iter.Value().Interface()
newTempMap[mapKey(key)] = objToMap(mapV)
}
return newTempMap
case reflect.Ptr:
return objToMap(v.Elem().Interface())
default:
return obj
}
}