Re: [RFC 01/15] scripts/qapi: support type-based unions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 28.03.24 12:15, Markus Armbruster wrote:
Vladimir Sementsov-Ogievskiy <vsementsov@xxxxxxxxxxxxxx> writes:

Look at block-job-change command: we have to specify both 'id' to chose
the job to operate on and 'type' for QAPI union be parsed. But for user
this looks redundant: when we specify 'id', QEMU should be able to get
corresponding job's type.

This commit brings such a possibility: just specify some Enum type as
'discriminator', and define a function somewhere with prototype

bool YourUnionType_mapper(YourUnionType *, EnumType *out, Error **errp)

Further commits will use this functionality to upgrade block-job-change
interface and introduce some new interfaces.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@xxxxxxxxxxxxxx>
---
  scripts/qapi/introspect.py |  5 +++-
  scripts/qapi/schema.py     | 50 +++++++++++++++++++++++---------------
  scripts/qapi/types.py      |  3 ++-
  scripts/qapi/visit.py      | 43 ++++++++++++++++++++++++++------
  4 files changed, 73 insertions(+), 28 deletions(-)

I believe you need to update docs/devel/qapi-code-gen.rst.

Current text:

     Union types
     -----------

     Syntax::

         UNION = { 'union': STRING,
                   'base': ( MEMBERS | STRING ),
                   'discriminator': STRING,
                   'data': BRANCHES,
                   '*if': COND,
                   '*features': FEATURES }
         BRANCHES = { BRANCH, ... }
         BRANCH = STRING : TYPE-REF
                | STRING : { 'type': TYPE-REF, '*if': COND }

     Member 'union' names the union type.

     The 'base' member defines the common members.  If it is a MEMBERS_
     object, it defines common members just like a struct type's 'data'
     member defines struct type members.  If it is a STRING, it names a
     struct type whose members are the common members.

     Member 'discriminator' must name a non-optional enum-typed member of
     the base struct.  That member's value selects a branch by its name.
     If no such branch exists, an empty branch is assumed.

If I understand your commit message correctly, this paragraph is no
longer true.


Right. Like this:

Member 'discriminator' must name either a non-optional enum-typed member, or an enum type name. (and more description follow, about user defined function and so on).


Do you think that mixing member name and type name here is OK? Or should I instead add another field 'discriminator-type', so that exactly one of 'discriminator' and 'discriminator-type' should be in union definition?



     Each BRANCH of the 'data' object defines a branch of the union.  A
     union must have at least one branch.

     The BRANCH's STRING name is the branch name.  It must be a value of
     the discriminator enum type.

     The BRANCH's value defines the branch's properties, in particular its
     type.  The type must a struct type.  The form TYPE-REF_ is shorthand
     for :code:`{ 'type': TYPE-REF }`.

     In the Client JSON Protocol, a union is represented by an object with
     the common members (from the base type) and the selected branch's
     members.  The two sets of member names must be disjoint.

     Example::

      { 'enum': 'BlockdevDriver', 'data': [ 'file', 'qcow2' ] }
      { 'union': 'BlockdevOptions',
        'base': { 'driver': 'BlockdevDriver', '*read-only': 'bool' },
        'discriminator': 'driver',
        'data': { 'file': 'BlockdevOptionsFile',
                  'qcow2': 'BlockdevOptionsQcow2' } }

     Resulting in these JSON objects::

      { "driver": "file", "read-only": true,
        "filename": "/some/place/my-image" }
      { "driver": "qcow2", "read-only": false,
        "backing": "/some/place/my-image", "lazy-refcounts": true }

     The order of branches need not match the order of the enum values.
     The branches need not cover all possible enum values.  In the
     resulting generated C data types, a union is represented as a struct
     with the base members in QAPI schema order, and then a union of
     structures for each branch of the struct.

     The optional 'if' member specifies a conditional.  See `Configuring
     the schema`_ below for more on this.

     The optional 'features' member specifies features.  See Features_
     below for more on this.


--
Best regards,
Vladimir
_______________________________________________
Devel mailing list -- devel@xxxxxxxxxxxxxxxxx
To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxx




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux