qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH v5 01/28] qapi: Document type-safety considerati


From: Markus Armbruster
Subject: Re: [Qemu-devel] [PATCH v5 01/28] qapi: Document type-safety considerations
Date: Wed, 01 Apr 2015 17:29:07 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux)

Eric Blake <address@hidden> writes:

[...]
>  === Union types ===
>
> -Union types are used to let the user choose between several different data
> -types.  A union type is defined using a dictionary as explained in the
> -following paragraphs.
> +Usage: { 'union': 'str', 'data': 'dict' }
> +or:    { 'union': 'str', 'data': 'dict', 'base': 'complex-type-name',
> +         'discriminator': 'enum-member-of-base' }
> +or:    { 'union': 'str', 'data': 'dict', 'discriminator': {} }
>
> +Union types are used to let the user choose between several different
> +data types.  There are three flavors: simple (no discriminator), flat
> +(a base type is mandatory, and discriminator is the name of an enum
> +field within that base type), and anonymous (discriminator is an
> +empty dictionary).  A union type is defined using a data dictionary as
> +explained in the following paragraphs.
>
> -A simple union type defines a mapping from discriminator values to data types
> -like in this example:
> +A simple union type defines a mapping from automatic discriminator
> +values to data types like in this example:
>
>   { 'type': 'FileOptions', 'data': { 'filename': 'str' } }
>   { 'type': 'Qcow2Options',
> @@ -132,10 +273,17 @@ specified data type corresponding to the discriminator 
> value:
>   { "type": "qcow2", "data" : { "backing-file": "/some/place/my-image",
>                                 "lazy-refcounts": true } }
>
> +Additionally, an implicit C enum NameKind is created, corresponding to
> +the union Name, for accessing the various branches of the union.  No
> +branch of the union can be named 'max', as this would collide with the
> +implicit enum.
>
> -A union definition can specify a complex type as its base. In this case, the
> -fields of the complex type are included as top-level fields of the union
> -dictionary in the QMP wire format. An example definition is:
> +
> +A flat union definition specifies a complex type as its base, and
> +avoids nesting on the wire.  In this case, the fields of the complex
> +type are included as top-level fields of the union dictionary in the
> +QMP wire format, and the 'discriminator' field must be the name of an
> +enum-typed member of the base type. An example definition is:
>
>   { 'type': 'BlockdevCommonOptions', 'data': { 'readonly': 'bool' } }
>   { 'union': 'BlockdevOptions',
      'base': 'BlockdevCommonOptions',
      'data': { 'raw': 'RawOptions',
                'qcow2': 'Qcow2Options' } }

Where's 'discriminator'?

   And it looks like this on the wire:

    { "type": "qcow2",
      "readonly": false,
>     "data" : { "backing-file": "/some/place/my-image",
>                "lazy-refcounts": true } }

Is the variant part really wrapped in "data"?

Here's the real schema's flat union BlockdevOptions:

    { 'union': 'BlockdevOptions',
      'base': 'BlockdevOptionsBase',
      'discriminator': 'driver',
      'data': {
          'qcow2':      'BlockdevOptionsQcow2',
          'raw':        'BlockdevOptionsGenericFormat',
[many more omitted...]
      } }

Same thing, just different names.

One the wire, it looks like

    { "driver": "qcow2",
      "id": "disk1",
      "file": { "driver": "file", "filename": "tmp.qcow2" } }

>
> -
> -Flat union types avoid the nesting on the wire. They are used whenever a
> -specific field of the base type is declared as the discriminator ('type' is
> -then no longer generated). The discriminator must be of enumeration type.
> -The above example can then be modified as follows:
> +Notice that in a flat union, a 'type' field is no longer generated,
> +and the keys of the 'data' dictionary must match the valid values for
> +the discriminator (although not necessarily in the same order). The
> +above example for simple unions can be modified to a flat union as
> +follows:
>
>   { 'enum': 'BlockdevDriver', 'data': [ 'raw', 'qcow2' ] }
>   { 'type': 'BlockdevCommonOptions',
      'data': { 'driver': 'BlockdevDriver', 'readonly': 'bool' } }
    { 'union': 'BlockdevOptions',
      'base': 'BlockdevCommonOptions',
      'discriminator': 'driver',
      'data': { 'raw': 'RawOptions',
                'qcow2': 'Qcow2Options' } }

   Resulting in this JSON object:

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

This actually matches the above example with the "data" wrapper peeled
off the variant part.

[...]



reply via email to

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