#include "qemu/osdep.h"
#include "hw/qdev-properties.h"
#include "qapi/error.h"
#include "qapi/qapi-types-misc.h"
#include "qapi/qmp/qerror.h"
#include "qapi/qmp/qlist.h"
#include "qemu/ctype.h"
#include "qemu/error-report.h"
#include "qapi/visitor.h"
#include "qemu/units.h"
#include "qemu/cutils.h"
#include "qdev-prop-internal.h"
#include "qom/qom-qobject.h"

void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
                                  Error **errp)
{
    if (dev->id) {
        error_setg(errp, "Attempt to set property '%s' on device '%s' "
                   "(type '%s') after it was realized", name, dev->id,
                   object_get_typename(OBJECT(dev)));
    } else {
        error_setg(errp, "Attempt to set property '%s' on anonymous device "
                   "(type '%s') after it was realized", name,
                   object_get_typename(OBJECT(dev)));
    }
}

/* returns: true if property is allowed to be set, false otherwise */
static bool qdev_prop_allow_set(Object *obj, const char *name,
                                const PropertyInfo *info, Error **errp)
{
    DeviceState *dev = DEVICE(obj);

    if (dev->realized && !info->realized_set_allowed) {
        qdev_prop_set_after_realize(dev, name, errp);
        return false;
    }
    return true;
}

void qdev_prop_allow_set_link_before_realize(const Object *obj,
                                             const char *name,
                                             Object *val, Error **errp)
{
    DeviceState *dev = DEVICE(obj);

    if (dev->realized) {
        error_setg(errp, "Attempt to set link property '%s' on device '%s' "
                   "(type '%s') after it was realized",
                   name, dev->id, object_get_typename(obj));
    }
}

void *object_field_prop_ptr(Object *obj, Property *prop)
{
    void *ptr = obj;
    ptr += prop->offset;
    return ptr;
}

static void field_prop_get(Object *obj, Visitor *v, const char *name,
                           void *opaque, Error **errp)
{
    Property *prop = opaque;
    return prop->info->get(obj, v, name, opaque, errp);
}

/**
 * field_prop_getter: Return getter function to be used for property
 *
 * Return value can be NULL if @info has no getter function.
 */
static ObjectPropertyAccessor *field_prop_getter(const PropertyInfo *info)
{
    return info->get ? field_prop_get : NULL;
}

static void field_prop_set(Object *obj, Visitor *v, const char *name,
                           void *opaque, Error **errp)
{
    Property *prop = opaque;

    if (!qdev_prop_allow_set(obj, name, prop->info, errp)) {
        return;
    }

    return prop->info->set(obj, v, name, opaque, errp);
}

/**
 * field_prop_setter: Return setter function to be used for property
 *
 * Return value can be NULL if @info has not setter function.
 */
static ObjectPropertyAccessor *field_prop_setter(const PropertyInfo *info)
{
    return info->set ? field_prop_set : NULL;
}

void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
                            void *opaque, Error **errp)
{
    Property *prop = opaque;
    int *ptr = object_field_prop_ptr(obj, prop);

    visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
}

void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
                            void *opaque, Error **errp)
{
    Property *prop = opaque;
    int *ptr = object_field_prop_ptr(obj, prop);

    visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
}

void qdev_propinfo_set_default_value_enum(ObjectProperty *op,
                                          const Property *prop)
{
    object_property_set_default_str(op,
        qapi_enum_lookup(prop->info->enum_table, prop->defval.i));
}

const PropertyInfo qdev_prop_enum = {
    .name  = "enum",
    .get   = qdev_propinfo_get_enum,
    .set   = qdev_propinfo_set_enum,
    .set_default_value = qdev_propinfo_set_default_value_enum,
};

/* Bit */

static uint32_t qdev_get_prop_mask(Property *prop)
{
    assert(prop->info == &qdev_prop_bit);
    return 0x1 << prop->bitnr;
}

static void bit_prop_set(Object *obj, Property *props, bool val)
{
    uint32_t *p = object_field_prop_ptr(obj, props);
    uint32_t mask = qdev_get_prop_mask(props);
    if (val) {
        *p |= mask;
    } else {
        *p &= ~mask;
    }
}

static void prop_get_bit(Object *obj, Visitor *v, const char *name,
                         void *opaque, Error **errp)
{
    Property *prop = opaque;
    uint32_t *p = object_field_prop_ptr(obj, prop);
    bool value = (*p & qdev_get_prop_mask(prop)) != 0;

    visit_type_bool(v, name, &value, errp);
}

static void prop_set_bit(Object *obj, Visitor *v, const char *name,
                         void *opaque, Error **errp)
{
    Property *prop = opaque;
    bool value;

    if (!visit_type_bool(v, name, &value, errp)) {
        return;
    }
    bit_prop_set(obj, prop, value);
}

static void set_default_value_bool(ObjectProperty *op, const Property *prop)
{
    object_property_set_default_bool(op, prop->defval.u);
}

const PropertyInfo qdev_prop_bit = {
    .name  = "bool",
    .description = "on/off",
    .get   = prop_get_bit,
    .set   = prop_set_bit,
    .set_default_value = set_default_value_bool,
};

/* Bit64 */

static uint64_t qdev_get_prop_mask64(Property *prop)
{
    assert(prop->info == &qdev_prop_bit64);
    return 0x1ull << prop->bitnr;
}

static void bit64_prop_set(Object *obj, Property *props, bool val)
{
    uint64_t *p = object_field_prop_ptr(obj, props);
    uint64_t mask = qdev_get_prop_mask64(props);
    if (val) {
        *p |= mask;
    } else {
        *p &= ~mask;
    }
}

static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
                           void *opaque, Error **errp)
{
    Property *prop = opaque;
    uint64_t *p = object_field_prop_ptr(obj, prop);
    bool value = (*p & qdev_get_prop_mask64(prop)) != 0;

    visit_type_bool(v, name, &value, errp);
}

static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
                           void *opaque, Error **errp)
{
    Property *prop = opaque;
    bool value;

    if (!visit_type_bool(v, name, &value, errp)) {
        return;
    }
    bit64_prop_set(obj, prop, value);
}

const PropertyInfo qdev_prop_bit64 = {
    .name  = "bool",
    .description = "on/off",
    .get   = prop_get_bit64,
    .set   = prop_set_bit64,
    .set_default_value = set_default_value_bool,
};

/* --- bool --- */

static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
{
    Property *prop = opaque;
    bool *ptr = object_field_prop_ptr(obj, prop);

    visit_type_bool(v, name, ptr, errp);
}

static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
{
    Property *prop = opaque;
    bool *ptr = object_field_prop_ptr(obj, prop);

    visit_type_bool(v, name, ptr, errp);
}

const PropertyInfo qdev_prop_bool = {
    .name  = "bool",
    .get   = get_bool,
    .set   = set_bool,
    .set_default_value = set_default_value_bool,
};

/* --- 8bit integer --- */

static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
{
    Property *prop = opaque;
    uint8_t *ptr = object_field_prop_ptr(obj, prop);

    visit_type_uint8(v, name, ptr, errp);
}

static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
{
    Property *prop = opaque;
    uint8_t *ptr = object_field_prop_ptr(obj, prop);

    visit_type_uint8(v, name, ptr, errp);
}

void qdev_propinfo_set_default_value_int(ObjectProperty *op,
                                         const Property *prop)
{
    object_property_set_default_int(op, prop->defval.i);
}

void qdev_propinfo_set_default_value_uint(ObjectProperty *op,
                                          const Property *prop)
{
    object_property_set_default_uint(op, prop->defval.u);
}

const PropertyInfo qdev_prop_uint8 = {
    .name  = "uint8",
    .get   = get_uint8,
    .set   = set_uint8,
    .set_default_value = qdev_propinfo_set_default_value_uint,
};

/* --- 16bit integer --- */

static void get_uint16(Object *obj, Visitor *v, const char *name,
                       void *opaque, Error **errp)
{
    Property *prop = opaque;
    uint16_t *ptr = object_field_prop_ptr(obj, prop);

    visit_type_uint16(v, name, ptr, errp);
}

static void set_uint16(Object *obj, Visitor *v, const char *name,
                       void *opaque, Error **errp)
{
    Property *prop = opaque;
    uint16_t *ptr = object_field_prop_ptr(obj, prop);

    visit_type_uint16(v, name, ptr, errp);
}

const PropertyInfo qdev_prop_uint16 = {
    .name  = "uint16",
    .get   = get_uint16,
    .set   = set_uint16,
    .set_default_value = qdev_propinfo_set_default_value_uint,
};

/* --- 32bit integer --- */

static void get_uint32(Object *obj, Visitor *v, const char *name,
                       void *opaque, Error **errp)
{
    Property *prop = opaque;
    uint32_t *ptr = object_field_prop_ptr(obj, prop);

    visit_type_uint32(v, name, ptr, errp);
}

static void set_uint32(Object *obj, Visitor *v, const char *name,
                       void *opaque, Error **errp)
{
    Property *prop = opaque;
    uint32_t *ptr = object_field_prop_ptr(obj, prop);

    visit_type_uint32(v, name, ptr, errp);
}

void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name,
                             void *opaque, Error **errp)
{
    Property *prop = opaque;
    int32_t *ptr = object_field_prop_ptr(obj, prop);

    visit_type_int32(v, name, ptr, errp);
}

static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
{
    Property *prop = opaque;
    int32_t *ptr = object_field_prop_ptr(obj, prop);

    visit_type_int32(v, name, ptr, errp);
}

const PropertyInfo qdev_prop_uint32 = {
    .name  = "uint32",
    .get   = get_uint32,
    .set   = set_uint32,
    .set_default_value = qdev_propinfo_set_default_value_uint,
};

const PropertyInfo qdev_prop_int32 = {
    .name  = "int32",
    .get   = qdev_propinfo_get_int32,
    .set   = set_int32,
    .set_default_value = qdev_propinfo_set_default_value_int,
};

/* --- 64bit integer --- */

static void get_uint64(Object *obj, Visitor *v, const char *name,
                       void *opaque, Error **errp)
{
    Property *prop = opaque;
    uint64_t *ptr = object_field_prop_ptr(obj, prop);

    visit_type_uint64(v, name, ptr, errp);
}

static void set_uint64(Object *obj, Visitor *v, const char *name,
                       void *opaque, Error **errp)
{
    Property *prop = opaque;
    uint64_t *ptr = object_field_prop_ptr(obj, prop);

    visit_type_uint64(v, name, ptr, errp);
}

static void get_int64(Object *obj, Visitor *v, const char *name,
                      void *opaque, Error **errp)
{
    Property *prop = opaque;
    int64_t *ptr = object_field_prop_ptr(obj, prop);

    visit_type_int64(v, name, ptr, errp);
}

static void set_int64(Object *obj, Visitor *v, const char *name,
                      void *opaque, Error **errp)
{
    Property *prop = opaque;
    int64_t *ptr = object_field_prop_ptr(obj, prop);

    visit_type_int64(v, name, ptr, errp);
}

const PropertyInfo qdev_prop_uint64 = {
    .name  = "uint64",
    .get   = get_uint64,
    .set   = set_uint64,
    .set_default_value = qdev_propinfo_set_default_value_uint,
};

const PropertyInfo qdev_prop_int64 = {
    .name  = "int64",
    .get   = get_int64,
    .set   = set_int64,
    .set_default_value = qdev_propinfo_set_default_value_int,
};

static void set_uint64_checkmask(Object *obj, Visitor *v, const char *name,
                      void *opaque, Error **errp)
{
    Property *prop = opaque;
    uint64_t *ptr = object_field_prop_ptr(obj, prop);

    visit_type_uint64(v, name, ptr, errp);
    if (*ptr & ~prop->bitmask) {
        error_setg(errp, "Property value for '%s' has bits outside mask '0x%" PRIx64 "'",
                   name, prop->bitmask);
    }
}

const PropertyInfo qdev_prop_uint64_checkmask = {
    .name  = "uint64",
    .get   = get_uint64,
    .set   = set_uint64_checkmask,
};

/* --- string --- */

static void release_string(Object *obj, const char *name, void *opaque)
{
    Property *prop = opaque;
    g_free(*(char **)object_field_prop_ptr(obj, prop));
}

static void get_string(Object *obj, Visitor *v, const char *name,
                       void *opaque, Error **errp)
{
    Property *prop = opaque;
    char **ptr = object_field_prop_ptr(obj, prop);

    if (!*ptr) {
        char *str = (char *)"";
        visit_type_str(v, name, &str, errp);
    } else {
        visit_type_str(v, name, ptr, errp);
    }
}

static void set_string(Object *obj, Visitor *v, const char *name,
                       void *opaque, Error **errp)
{
    Property *prop = opaque;
    char **ptr = object_field_prop_ptr(obj, prop);
    char *str;

    if (!visit_type_str(v, name, &str, errp)) {
        return;
    }
    g_free(*ptr);
    *ptr = str;
}

const PropertyInfo qdev_prop_string = {
    .name  = "str",
    .release = release_string,
    .get   = get_string,
    .set   = set_string,
};

/* --- on/off/auto --- */

const PropertyInfo qdev_prop_on_off_auto = {
    .name = "OnOffAuto",
    .description = "on/off/auto",
    .enum_table = &OnOffAuto_lookup,
    .get = qdev_propinfo_get_enum,
    .set = qdev_propinfo_set_enum,
    .set_default_value = qdev_propinfo_set_default_value_enum,
};

/* --- 32bit unsigned int 'size' type --- */

void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name,
                              void *opaque, Error **errp)
{
    Property *prop = opaque;
    uint32_t *ptr = object_field_prop_ptr(obj, prop);
    uint64_t value = *ptr;

    visit_type_size(v, name, &value, errp);
}

static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
                       Error **errp)
{
    Property *prop = opaque;
    uint32_t *ptr = object_field_prop_ptr(obj, prop);
    uint64_t value;

    if (!visit_type_size(v, name, &value, errp)) {
        return;
    }

    if (value > UINT32_MAX) {
        error_setg(errp,
                   "Property %s.%s doesn't take value %" PRIu64
                   " (maximum: %u)",
                   object_get_typename(obj), name, value, UINT32_MAX);
        return;
    }

    *ptr = value;
}

const PropertyInfo qdev_prop_size32 = {
    .name  = "size",
    .get = qdev_propinfo_get_size32,
    .set = set_size32,
    .set_default_value = qdev_propinfo_set_default_value_uint,
};

/* --- support for array properties --- */

typedef struct ArrayElementList ArrayElementList;

struct ArrayElementList {
    ArrayElementList *next;
    void *value;
};

/*
 * Given an array property @parent_prop in @obj, return a Property for a
 * specific element of the array. Arrays are backed by an uint32_t length field
 * and an element array. @elem points at an element in this element array.
 */
static Property array_elem_prop(Object *obj, Property *parent_prop,
                                const char *name, char *elem)
{
    return (Property) {
        .info = parent_prop->arrayinfo,
        .name = name,
        /*
         * This ugly piece of pointer arithmetic sets up the offset so
         * that when the underlying release hook calls qdev_get_prop_ptr
         * they get the right answer despite the array element not actually
         * being inside the device struct.
         */
        .offset = (uintptr_t)elem - (uintptr_t)obj,
    };
}

/*
 * Object property release callback for array properties: We call the
 * underlying element's property release hook for each element.
 *
 * Note that it is the responsibility of the individual device's deinit
 * to free the array proper.
 */
static void release_prop_array(Object *obj, const char *name, void *opaque)
{
    Property *prop = opaque;
    uint32_t *alenptr = object_field_prop_ptr(obj, prop);
    void **arrayptr = (void *)obj + prop->arrayoffset;
    char *elem = *arrayptr;
    int i;

    if (!prop->arrayinfo->release) {
        return;
    }

    for (i = 0; i < *alenptr; i++) {
        Property elem_prop = array_elem_prop(obj, prop, name, elem);
        prop->arrayinfo->release(obj, NULL, &elem_prop);
        elem += prop->arrayfieldsize;
    }
}

/*
 * Setter for an array property. This sets both the array length (which
 * is technically the property field in the object) and the array itself
 * (a pointer to which is stored in the additional field described by
 * prop->arrayoffset).
 */
static void set_prop_array(Object *obj, Visitor *v, const char *name,
                           void *opaque, Error **errp)
{
    ERRP_GUARD();
    Property *prop = opaque;
    uint32_t *alenptr = object_field_prop_ptr(obj, prop);
    void **arrayptr = (void *)obj + prop->arrayoffset;
    ArrayElementList *list, *elem, *next;
    const size_t size = sizeof(*list);
    char *elemptr;
    bool ok = true;

    if (*alenptr) {
        error_setg(errp, "array size property %s may not be set more than once",
                   name);
        return;
    }

    if (!visit_start_list(v, name, (GenericList **) &list, size, errp)) {
        return;
    }

    /* Read the whole input into a temporary list */
    elem = list;
    while (elem) {
        Property elem_prop;

        elem->value = g_malloc0(prop->arrayfieldsize);
        elem_prop = array_elem_prop(obj, prop, name, elem->value);
        prop->arrayinfo->set(obj, v, NULL, &elem_prop, errp);
        if (*errp) {
            ok = false;
            goto out_obj;
        }
        if (*alenptr == INT_MAX) {
            error_setg(errp, "array is too big");
            return;
        }
        (*alenptr)++;
        elem = (ArrayElementList *) visit_next_list(v, (GenericList*) elem,
                                                    size);
    }

    ok = visit_check_list(v, errp);
out_obj:
    visit_end_list(v, (void**) &list);

    if (!ok) {
        for (elem = list; elem; elem = next) {
            Property elem_prop = array_elem_prop(obj, prop, name,
                                                 elem->value);
            if (prop->arrayinfo->release) {
                prop->arrayinfo->release(obj, NULL, &elem_prop);
            }
            next = elem->next;
            g_free(elem->value);
            g_free(elem);
        }
        return;
    }

    /*
     * Now that we know how big the array has to be, move the data over to a
     * linear array and free the temporary list.
     */
    *arrayptr = g_malloc_n(*alenptr, prop->arrayfieldsize);
    elemptr = *arrayptr;
    for (elem = list; elem; elem = next) {
        memcpy(elemptr, elem->value, prop->arrayfieldsize);
        elemptr += prop->arrayfieldsize;
        next = elem->next;
        g_free(elem->value);
        g_free(elem);
    }
}

static void get_prop_array(Object *obj, Visitor *v, const char *name,
                           void *opaque, Error **errp)
{
    ERRP_GUARD();
    Property *prop = opaque;
    uint32_t *alenptr = object_field_prop_ptr(obj, prop);
    void **arrayptr = (void *)obj + prop->arrayoffset;
    char *elemptr = *arrayptr;
    ArrayElementList *list = NULL, *elem;
    ArrayElementList **tail = &list;
    const size_t size = sizeof(*list);
    int i;
    bool ok;

    /* At least the string output visitor needs a real list */
    for (i = 0; i < *alenptr; i++) {
        elem = g_new0(ArrayElementList, 1);
        elem->value = elemptr;
        elemptr += prop->arrayfieldsize;

        *tail = elem;
        tail = &elem->next;
    }

    if (!visit_start_list(v, name, (GenericList **) &list, size, errp)) {
        return;
    }

    elem = list;
    while (elem) {
        Property elem_prop = array_elem_prop(obj, prop, name, elem->value);
        prop->arrayinfo->get(obj, v, NULL, &elem_prop, errp);
        if (*errp) {
            goto out_obj;
        }
        elem = (ArrayElementList *) visit_next_list(v, (GenericList*) elem,
                                                    size);
    }

    /* visit_check_list() can only fail for input visitors */
    ok = visit_check_list(v, errp);
    assert(ok);

out_obj:
    visit_end_list(v, (void**) &list);

    while (list) {
        elem = list;
        list = elem->next;
        g_free(elem);
    }
}

static void default_prop_array(ObjectProperty *op, const Property *prop)
{
    object_property_set_default_list(op);
}

const PropertyInfo qdev_prop_array = {
    .name = "list",
    .get = get_prop_array,
    .set = set_prop_array,
    .release = release_prop_array,
    .set_default_value = default_prop_array,
};

/* --- public helpers --- */

static Property *qdev_prop_walk(Property *props, const char *name)
{
    if (!props) {
        return NULL;
    }
    while (props->name) {
        if (strcmp(props->name, name) == 0) {
            return props;
        }
        props++;
    }
    return NULL;
}

static Property *qdev_prop_find(DeviceState *dev, const char *name)
{
    ObjectClass *class;
    Property *prop;

    /* device properties */
    class = object_get_class(OBJECT(dev));
    do {
        prop = qdev_prop_walk(DEVICE_CLASS(class)->props_, name);
        if (prop) {
            return prop;
        }
        class = object_class_get_parent(class);
    } while (class != object_class_by_name(TYPE_DEVICE));

    return NULL;
}

void error_set_from_qdev_prop_error(Error **errp, int ret, Object *obj,
                                    const char *name, const char *value)
{
    switch (ret) {
    case -EEXIST:
        error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
                  object_get_typename(obj), name, value);
        break;
    default:
    case -EINVAL:
        error_setg(errp, QERR_PROPERTY_VALUE_BAD,
                   object_get_typename(obj), name, value);
        break;
    case -ENOENT:
        error_setg(errp, "Property '%s.%s' can't find value '%s'",
                  object_get_typename(obj), name, value);
        break;
    case 0:
        break;
    }
}

void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
{
    object_property_set_bool(OBJECT(dev), name, value, &error_abort);
}

void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
{
    object_property_set_int(OBJECT(dev), name, value, &error_abort);
}

void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
{
    object_property_set_int(OBJECT(dev), name, value, &error_abort);
}

void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
{
    object_property_set_int(OBJECT(dev), name, value, &error_abort);
}

void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
{
    object_property_set_int(OBJECT(dev), name, value, &error_abort);
}

void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
{
    object_property_set_int(OBJECT(dev), name, value, &error_abort);
}

void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
{
    object_property_set_str(OBJECT(dev), name, value, &error_abort);
}

void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
{
    Property *prop;

    prop = qdev_prop_find(dev, name);
    object_property_set_str(OBJECT(dev), name,
                            qapi_enum_lookup(prop->info->enum_table, value),
                            &error_abort);
}

void qdev_prop_set_array(DeviceState *dev, const char *name, QList *values)
{
    object_property_set_qobject(OBJECT(dev), name, QOBJECT(values),
                                &error_abort);
    qobject_unref(values);
}

static GPtrArray *global_props(void)
{
    static GPtrArray *gp;

    if (!gp) {
        gp = g_ptr_array_new();
    }

    return gp;
}

void qdev_prop_register_global(GlobalProperty *prop)
{
    g_ptr_array_add(global_props(), prop);
}

const GlobalProperty *qdev_find_global_prop(Object *obj,
                                            const char *name)
{
    GPtrArray *props = global_props();
    const GlobalProperty *p;
    int i;

    for (i = 0; i < props->len; i++) {
        p = g_ptr_array_index(props, i);
        if (object_dynamic_cast(obj, p->driver)
            && !strcmp(p->property, name)) {
            return p;
        }
    }
    return NULL;
}

int qdev_prop_check_globals(void)
{
    int i, ret = 0;

    for (i = 0; i < global_props()->len; i++) {
        GlobalProperty *prop;
        ObjectClass *oc;
        DeviceClass *dc;

        prop = g_ptr_array_index(global_props(), i);
        if (prop->used) {
            continue;
        }
        oc = object_class_by_name(prop->driver);
        oc = object_class_dynamic_cast(oc, TYPE_DEVICE);
        if (!oc) {
            warn_report("global %s.%s has invalid class name",
                        prop->driver, prop->property);
            ret = 1;
            continue;
        }
        dc = DEVICE_CLASS(oc);
        if (!dc->hotpluggable && !prop->used) {
            warn_report("global %s.%s=%s not used",
                        prop->driver, prop->property, prop->value);
            ret = 1;
            continue;
        }
    }
    return ret;
}

void qdev_prop_set_globals(DeviceState *dev)
{
    object_apply_global_props(OBJECT(dev), global_props(),
                              dev->hotplugged ? NULL : &error_fatal);
}

/* --- 64bit unsigned int 'size' type --- */

static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
{
    Property *prop = opaque;
    uint64_t *ptr = object_field_prop_ptr(obj, prop);

    visit_type_size(v, name, ptr, errp);
}

static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
{
    Property *prop = opaque;
    uint64_t *ptr = object_field_prop_ptr(obj, prop);

    visit_type_size(v, name, ptr, errp);
}

const PropertyInfo qdev_prop_size = {
    .name  = "size",
    .get = get_size,
    .set = set_size,
    .set_default_value = qdev_propinfo_set_default_value_uint,
};

/* --- object link property --- */

static ObjectProperty *create_link_property(ObjectClass *oc, const char *name,
                                            Property *prop)
{
    return object_class_property_add_link(oc, name, prop->link_type,
                                          prop->offset,
                                          qdev_prop_allow_set_link_before_realize,
                                          OBJ_PROP_LINK_STRONG);
}

const PropertyInfo qdev_prop_link = {
    .name = "link",
    .create = create_link_property,
};

void qdev_property_add_static(DeviceState *dev, Property *prop)
{
    Object *obj = OBJECT(dev);
    ObjectProperty *op;

    assert(!prop->info->create);

    op = object_property_add(obj, prop->name, prop->info->name,
                             field_prop_getter(prop->info),
                             field_prop_setter(prop->info),
                             prop->info->release,
                             prop);

    object_property_set_description(obj, prop->name,
                                    prop->info->description);

    if (prop->set_default) {
        prop->info->set_default_value(op, prop);
        if (op->init) {
            op->init(obj, op);
        }
    }
}

static void qdev_class_add_property(DeviceClass *klass, const char *name,
                                    Property *prop)
{
    ObjectClass *oc = OBJECT_CLASS(klass);
    ObjectProperty *op;

    if (prop->info->create) {
        op = prop->info->create(oc, name, prop);
    } else {
        op = object_class_property_add(oc,
                                       name, prop->info->name,
                                       field_prop_getter(prop->info),
                                       field_prop_setter(prop->info),
                                       prop->info->release,
                                       prop);
    }
    if (prop->set_default) {
        prop->info->set_default_value(op, prop);
    }
    object_class_property_set_description(oc, name, prop->info->description);
}

/**
 * Legacy property handling
 */

static void qdev_get_legacy_property(Object *obj, Visitor *v,
                                     const char *name, void *opaque,
                                     Error **errp)
{
    Property *prop = opaque;

    char buffer[1024];
    char *ptr = buffer;

    prop->info->print(obj, prop, buffer, sizeof(buffer));
    visit_type_str(v, name, &ptr, errp);
}

/**
 * qdev_class_add_legacy_property:
 * @dev: Device to add the property to.
 * @prop: The qdev property definition.
 *
 * Add a legacy QOM property to @dev for qdev property @prop.
 *
 * Legacy properties are string versions of QOM properties.  The format of
 * the string depends on the property type.  Legacy properties are only
 * needed for "info qtree".
 *
 * Do not use this in new code!  QOM Properties added through this interface
 * will be given names in the "legacy" namespace.
 */
static void qdev_class_add_legacy_property(DeviceClass *dc, Property *prop)
{
    g_autofree char *name = NULL;

    /* Register pointer properties as legacy properties */
    if (!prop->info->print && prop->info->get) {
        return;
    }

    name = g_strdup_printf("legacy-%s", prop->name);
    object_class_property_add(OBJECT_CLASS(dc), name, "str",
        prop->info->print ? qdev_get_legacy_property : prop->info->get,
        NULL, NULL, prop);
}

void device_class_set_props(DeviceClass *dc, Property *props)
{
    Property *prop;

    dc->props_ = props;
    for (prop = props; prop && prop->name; prop++) {
        qdev_class_add_legacy_property(dc, prop);
        qdev_class_add_property(dc, prop->name, prop);
    }
}

void qdev_alias_all_properties(DeviceState *target, Object *source)
{
    ObjectClass *class;
    Property *prop;

    class = object_get_class(OBJECT(target));
    do {
        DeviceClass *dc = DEVICE_CLASS(class);

        for (prop = dc->props_; prop && prop->name; prop++) {
            object_property_add_alias(source, prop->name,
                                      OBJECT(target), prop->name);
        }
        class = object_class_get_parent(class);
    } while (class != object_class_by_name(TYPE_DEVICE));
}
