qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] RFC: 'alternate' qapi top-level expression [was: [PATCH v4


From: Eric Blake
Subject: [Qemu-devel] RFC: 'alternate' qapi top-level expression [was: [PATCH v4 12/19] qapi: Add some type check tests]
Date: Mon, 23 Mar 2015 09:33:10 -0600
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0

[revisiting this series, finally!]

On 09/25/2014 10:19 AM, Markus Armbruster wrote:

>> Return of an anon union isn't used yet, but _might_ make sense (as the
>> only feasible way of changing existing commands that return an array or
>> primitive extensible to instead return a dict) - 
> 
> Good point.
> 
>>                                                  except that back-compat
>> demands that we can't return a dict in place of a primitive unless the
>> arguments of the command are also enhanced (that is, older callers are
>> not expecting a dict, so we can't return a dict unless the caller
>> witnesses they are new enough by explicitly asking for a dict return).
> 
> I think we can keep things simple for now and reject anonymous unions.
> We can always relax the check when we run into a use.

In trying to code up what it would take to easily reject anonymous
unions from a return type, I'm realizing that it would be smarter to
quit mixing anonymous unions in with other unions.

Refresher course: on the wire, both a regular union:

QAPI:
 { 'type': 'Type1', 'data': { 'value': 'int' } }
 { 'union': 'Foo', 'data': { 'a': 'Type1', 'b': 'Type2' } }
 { 'command': 'bar', 'data': 'Foo' }
Wire:
 { "execute": "bar", "arguments": { "type": "a",
   "data": { "value": 1 } } }

and a flat union:

QAPI:
 { 'type': 'Type1', 'data': { 'value': 'int' } }
 { 'enum': 'Enum', 'data': [ 'a', 'b' ] }
 { 'type': 'Base', { 'switch': 'Enum' } }
 { 'union': 'Foo', 'base': 'Base', 'discriminator': 'switch',
   'data': { 'a': 'Type1', 'b': 'Type2' } }
 { 'command': 'bar', 'data': 'Foo' }
Wire:
 { "execute": "bar", "arguments": { "switch": "a",
   "value": 1 } }

happen to guarantee a top-level dictionary (plain unions always have a
two-element dictionary, flat unions are required to have a base type
which is itself a dictionary).  But an anonymous union is explicitly
allowing a multi-type variable, where the determination of which branch
of the union is made by the type of the variable.  Furthermore, we do
not allow two branches to have the same type, so at least one branch
must be a non-dictionary; but as _all_ QMP commands currently take a
dictionary for the "arguments" key, we do not want to allow:

QAPI:
 { 'type': 'Type1', 'data': { 'value': 'int' } }
 { 'union': 'Foo', 'discriminator': {},
   'data': { 'a': 'Type1', 'b': 'int' } }
 { 'command': 'bar', 'data': 'Foo' }
Wire:
 { "execute": "bar", "arguments": 1 }


Tracking all three qapi expressions as union types is making the
generator code a bit verbose, especially since the code generation for
all three is so distinct.


Proposal: I am proposing that we convert to an alternate syntax for what
we now term as anonymous unions.  It will not have any impact to the
wire representation of QMP, only to the qapi code generators.  The
proposal is simple: instead of using "'union':'Name',
'discriminator':{}", we instead use "'alternate': 'Foo'" when declaring
a type as an anonymous union (which, for obvious reasons, I would then
update the documentation to call an "alternate" instead of an "anonymous
union").

I'll go ahead and propose the patches (I've already done the bulk of the
conversion work, to prove that not many files were affected).

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]