qemu-devel
[Top][All Lists]
Advanced

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

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


From: Markus Armbruster
Subject: Re: [Qemu-devel] RFC: 'alternate' qapi top-level expression [was: [PATCH v4 12/19] qapi: Add some type check tests]
Date: Mon, 23 Mar 2015 20:28:55 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux)

Cc'ing Kevin as fair punishment for is previous work on QAPI code
generation in general, and union types in particular.

Eric Blake <address@hidden> writes:

> [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).

Yes.

>                                 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,

Even more severe: the JSON types have to be different!  Thus, at most
one can be a complex or union type, and at most one can be a string or
enum type.

>                                               so at least one branch
> must be a non-dictionary;

Correct.

>                           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 }

Yes, let's stay out of the generalization tar pits and stick to named
parameters, i.e. JSON object arguments.

> 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").

This separates tagged and untagged unions more clearly: reserve 'union'
for the two kinds of tagged unions, switch the untagged union to
'alternate'.

I don't mind.  Kevin, any objections?

> 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).

I'll gladly review.



reply via email to

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