mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-15 22:21:57 -06:00
docs/devel/qapi-code-gen: Improve QAPI schema language doc
We document the language by giving patterns of valid JSON objects. The patterns contain placeholders we don't define anywhere; their names have to speak for themselves. I guess they do, but I'd prefer a bit more rigor. Provide a grammar instead, and rework the text accordingly. Documentation for QAPI schema conditionals (commit967c885108
,6cc32b0e14
, 87adbbffd4..3e270dcacc) and feature flags (commit6a8c0b5102
) was bolted on. The sections documenting types, commands and events don't mention them. Section "Features" and "Configuring the schema" then provide additional syntax for types, commands and events. I hate that. Fix the sections documenting types, commands and events to provide accurate syntax, and point to "Features" and "Configuring the schema" for details. We talk about "(top-level) expressions other than include and pragma". Adopt more convenient terminology: a (top-level) expression is either a directive (include or pragma) or a definition (anything else). Avoid the terms "dictionary" and "key". Stick to JSON terminology "object" and "member name" instead. While there, make spacing more consistent. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20190913201349.24332-16-armbru@redhat.com>
This commit is contained in:
parent
634c82c163
commit
b6c37ebaaf
1 changed files with 366 additions and 218 deletions
|
@ -4,12 +4,12 @@ Copyright IBM Corp. 2011
|
||||||
Copyright (C) 2012-2016 Red Hat, Inc.
|
Copyright (C) 2012-2016 Red Hat, Inc.
|
||||||
|
|
||||||
This work is licensed under the terms of the GNU GPL, version 2 or
|
This work is licensed under the terms of the GNU GPL, version 2 or
|
||||||
later. See the COPYING file in the top-level directory.
|
later. See the COPYING file in the top-level directory.
|
||||||
|
|
||||||
== Introduction ==
|
== Introduction ==
|
||||||
|
|
||||||
QAPI is a native C API within QEMU which provides management-level
|
QAPI is a native C API within QEMU which provides management-level
|
||||||
functionality to internal and external users. For external
|
functionality to internal and external users. For external
|
||||||
users/processes, this interface is made available by a JSON-based wire
|
users/processes, this interface is made available by a JSON-based wire
|
||||||
format for the QEMU Monitor Protocol (QMP) for controlling qemu, as
|
format for the QEMU Monitor Protocol (QMP) for controlling qemu, as
|
||||||
well as the QEMU Guest Agent (QGA) for communicating with the guest.
|
well as the QEMU Guest Agent (QGA) for communicating with the guest.
|
||||||
|
@ -54,24 +54,49 @@ Differences:
|
||||||
|
|
||||||
* Numbers are not supported.
|
* Numbers are not supported.
|
||||||
|
|
||||||
A QAPI schema consists of a series of top-level expressions (JSON
|
A second layer of syntax defines the sequences of JSON texts that are
|
||||||
objects). Code and documentation is generated in schema definition
|
a correctly structured QAPI schema. We provide a grammar for this
|
||||||
order. Code order should not matter.
|
syntax in an EBNF-like notation:
|
||||||
|
|
||||||
The order of keys within JSON objects does not matter unless
|
* Production rules look like non-terminal = expression
|
||||||
|
* Concatenation: expression A B matches expression A, then B
|
||||||
|
* Alternation: expression A | B matches expression A or B
|
||||||
|
* Repetition: expression A... matches zero or more occurrences of
|
||||||
|
expression A
|
||||||
|
* Repetition: expression A, ... matches zero or more occurrences of
|
||||||
|
expression A separated by ,
|
||||||
|
* Grouping: expression ( A ) matches expression A
|
||||||
|
* JSON's structural characters are terminals: { } [ ] : ,
|
||||||
|
* JSON's literal names are terminals: false true null
|
||||||
|
* String literals enclosed in 'single quotes' are terminal, and match
|
||||||
|
this JSON string, with a leading '*' stripped off
|
||||||
|
* When JSON object member's name starts with '*', the member is
|
||||||
|
optional.
|
||||||
|
* The symbol STRING is a terminal, and matches any JSON string
|
||||||
|
* The symbol BOOL is a terminal, and matches JSON false or true
|
||||||
|
* ALL-CAPS words other than STRING are non-terminals
|
||||||
|
|
||||||
|
The order of members within JSON objects does not matter unless
|
||||||
explicitly noted.
|
explicitly noted.
|
||||||
|
|
||||||
There are eight kinds of top-level expressions: 'include', 'pragma',
|
A QAPI schema consists of a series of top-level expressions:
|
||||||
'command', 'struct', 'enum', 'union', 'alternate', and 'event'. These
|
|
||||||
are discussed in detail below.
|
|
||||||
|
|
||||||
In the rest of this document, usage lines are given for each
|
SCHEMA = TOP-LEVEL-EXPR...
|
||||||
expression type, with literal strings written in lower case and
|
|
||||||
placeholders written in capitals. If a literal string includes a
|
The top-level expressions are all JSON objects. Code and
|
||||||
prefix of '*', that key/value pair can be omitted from the expression.
|
documentation is generated in schema definition order. Code order
|
||||||
For example, a usage statement that includes '*base':STRUCT-NAME
|
should not matter.
|
||||||
means that an expression has an optional key 'base', which if present
|
|
||||||
must have a value that forms a struct name.
|
A top-level expressions is either a directive or a definition:
|
||||||
|
|
||||||
|
TOP-LEVEL-EXPR = DIRECTIVE | DEFINITION
|
||||||
|
|
||||||
|
There are two kinds of directives and six kinds of definitions:
|
||||||
|
|
||||||
|
DIRECTIVE = INCLUDE | PRAGMA
|
||||||
|
DEFINITION = ENUM | STRUCT | UNION | ALTERNATE | COMMAND | EVENT
|
||||||
|
|
||||||
|
These are discussed in detail below.
|
||||||
|
|
||||||
|
|
||||||
=== Built-in Types ===
|
=== Built-in Types ===
|
||||||
|
@ -101,16 +126,16 @@ The following types are predefined, and map to C as follows:
|
||||||
|
|
||||||
=== Include directives ===
|
=== Include directives ===
|
||||||
|
|
||||||
Usage: { 'include': STRING }
|
Syntax:
|
||||||
|
INCLUDE = { 'include': STRING }
|
||||||
|
|
||||||
The QAPI schema definitions can be modularized using the 'include' directive:
|
The QAPI schema definitions can be modularized using the 'include' directive:
|
||||||
|
|
||||||
{ 'include': 'path/to/file.json' }
|
{ 'include': 'path/to/file.json' }
|
||||||
|
|
||||||
The directive is evaluated recursively, and include paths are relative to the
|
The directive is evaluated recursively, and include paths are relative
|
||||||
file using the directive. Multiple includes of the same file are
|
to the file using the directive. Multiple includes of the same file
|
||||||
idempotent. No other keys should appear in the expression, and the include
|
are idempotent.
|
||||||
value should be a string.
|
|
||||||
|
|
||||||
As a matter of style, it is a good idea to have all files be
|
As a matter of style, it is a good idea to have all files be
|
||||||
self-contained, but at the moment, nothing prevents an included file
|
self-contained, but at the moment, nothing prevents an included file
|
||||||
|
@ -121,10 +146,12 @@ prevent incomplete include files.
|
||||||
|
|
||||||
=== Pragma directives ===
|
=== Pragma directives ===
|
||||||
|
|
||||||
Usage: { 'pragma': DICT }
|
Syntax:
|
||||||
|
PRAGMA = { 'pragma': { '*doc-required': BOOL,
|
||||||
|
'*returns-whitelist': [ STRING, ... ],
|
||||||
|
'*name-case-whitelist': [ STRING, ... ] } }
|
||||||
|
|
||||||
The pragma directive lets you control optional generator behavior.
|
The pragma directive lets you control optional generator behavior.
|
||||||
The dictionary's entries are pragma names and values.
|
|
||||||
|
|
||||||
Pragma's scope is currently the complete schema. Setting the same
|
Pragma's scope is currently the complete schema. Setting the same
|
||||||
pragma to different values in parts of the schema doesn't work.
|
pragma to different values in parts of the schema doesn't work.
|
||||||
|
@ -141,60 +168,95 @@ rules on use of upper- vs. lower-case letters. Default is none.
|
||||||
|
|
||||||
=== Enumeration types ===
|
=== Enumeration types ===
|
||||||
|
|
||||||
Usage: { 'enum': STRING, 'data': ARRAY-OF-STRING }
|
Syntax:
|
||||||
{ 'enum': STRING, '*prefix': STRING, 'data': ARRAY-OF-STRING }
|
ENUM = { 'enum': STRING,
|
||||||
|
'data': [ ENUM-VALUE, ... ],
|
||||||
|
'*prefix': STRING,
|
||||||
|
'*if': COND }
|
||||||
|
ENUM-VALUE = STRING
|
||||||
|
| { 'name': STRING, '*if': COND }
|
||||||
|
|
||||||
An enumeration type is a dictionary containing a single 'data' key
|
Member 'enum' names the enum type.
|
||||||
whose value is a list of strings. An example enumeration is:
|
|
||||||
|
Each member of the 'data' array defines a value of the enumeration
|
||||||
|
type. The form STRING is shorthand for { 'name': STRING }. The
|
||||||
|
'name' values must be be distinct.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
{ 'enum': 'MyEnum', 'data': [ 'value1', 'value2', 'value3' ] }
|
{ 'enum': 'MyEnum', 'data': [ 'value1', 'value2', 'value3' ] }
|
||||||
|
|
||||||
Nothing prevents an empty enumeration, although it is probably not
|
Nothing prevents an empty enumeration, although it is probably not
|
||||||
useful. The list of strings should be lower case; if an enum name
|
useful.
|
||||||
represents multiple words, use '-' between words. The string 'max' is
|
|
||||||
not allowed as an enum value, and values should not be repeated.
|
|
||||||
|
|
||||||
The enum constants will be named by using a heuristic to turn the
|
On the wire, an enumeration type's value is represented by its
|
||||||
type name into a set of underscore separated words. For the example
|
(string) name. In C, it's represented by an enumeration constant.
|
||||||
above, 'MyEnum' will turn into 'MY_ENUM' giving a constant name
|
These are of the form PREFIX_NAME, where PREFIX is derived from the
|
||||||
of 'MY_ENUM_VALUE1' for the first value. If the default heuristic
|
enumeration type's name, and NAME from the value's name. For the
|
||||||
does not result in a desirable name, the optional 'prefix' member
|
example above, the generator maps 'MyEnum' to MY_ENUM and 'value1' to
|
||||||
can be used when defining the enum.
|
VALUE1, resulting in the enumeration constant MY_ENUM_VALUE1. The
|
||||||
|
optional 'prefix' member overrides PREFIX.
|
||||||
|
|
||||||
The enumeration values are passed as strings over the Client JSON
|
The generated C enumeration constants have values 0, 1, ..., N-1 (in
|
||||||
Protocol, but are encoded as C enum integral values in generated code.
|
QAPI schema order), where N is the number of values. There is an
|
||||||
While the C code starts numbering at 0, it is better to use explicit
|
additional enumeration constant PREFIX__MAX with value N.
|
||||||
comparisons to enum values than implicit comparisons to 0; the C code
|
|
||||||
will also include a generated enum member ending in _MAX for tracking
|
Do not use string or an integer type when an enumeration type can do
|
||||||
the size of the enum, useful when using common functions for
|
the job satisfactorily.
|
||||||
converting between strings and enum values.
|
|
||||||
|
The optional 'if' member specifies a conditional. See "Configuring
|
||||||
|
the schema" below for more on this.
|
||||||
|
|
||||||
|
|
||||||
|
=== Type references and array types ===
|
||||||
|
|
||||||
|
Syntax:
|
||||||
|
TYPE-REF = STRING | ARRAY-TYPE
|
||||||
|
ARRAY-TYPE = [ STRING ]
|
||||||
|
|
||||||
|
A string denotes the type named by the string.
|
||||||
|
|
||||||
|
A one-element array containing a string denotes an array of the type
|
||||||
|
named by the string. Example: ['int'] denotes an array of 'int'.
|
||||||
|
|
||||||
For any struct that has a member that will only contain a finite set
|
|
||||||
of string values, using an enum type for that member is better than
|
|
||||||
open-coding the member to be type 'str'.
|
|
||||||
|
|
||||||
=== Struct types ===
|
=== Struct types ===
|
||||||
|
|
||||||
Usage: { 'struct': STRING, 'data': DICT, '*base': STRUCT-NAME }
|
Syntax:
|
||||||
|
STRUCT = { 'struct': STRING,
|
||||||
|
'data': MEMBERS,
|
||||||
|
'*base': STRING,
|
||||||
|
'*if': COND,
|
||||||
|
'*features': FEATURES }
|
||||||
|
MEMBERS = { MEMBER, ... }
|
||||||
|
MEMBER = STRING : TYPE-REF
|
||||||
|
| STRING : { 'type': TYPE-REF, '*if': COND }
|
||||||
|
|
||||||
A struct is a dictionary containing a single 'data' key whose value is
|
Member 'struct' names the struct type.
|
||||||
a dictionary; the dictionary may be empty. This corresponds to a
|
|
||||||
struct in C or an Object in JSON. Each value of the 'data' dictionary
|
Each MEMBER of the 'data' object defines a member of the struct type.
|
||||||
must be the name of a type, or a one-element array containing a type
|
|
||||||
name. An example of a struct is:
|
The MEMBER's STRING name consists of an optional '*' prefix and the
|
||||||
|
struct member name. If '*' is present, the member is optional.
|
||||||
|
|
||||||
|
The MEMBER's value defines its properties, in particular its type.
|
||||||
|
The form TYPE-REF is shorthand for { 'type': TYPE-REF }.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
{ 'struct': 'MyType',
|
{ 'struct': 'MyType',
|
||||||
'data': { 'member1': 'str', 'member2': 'int', '*member3': 'str' } }
|
'data': { 'member1': 'str', 'member2': ['int'], '*member3': 'str' } }
|
||||||
|
|
||||||
The use of '*' as a prefix to the name means the member is optional in
|
A struct type corresponds to a struct in C, and an object in JSON.
|
||||||
the corresponding JSON protocol usage.
|
The C struct's members are generated in QAPI schema order.
|
||||||
|
|
||||||
A struct definition can specify another struct as its base.
|
The optional 'base' member names a struct type whose members are to be
|
||||||
In this case, the members of the base type are included as top-level members
|
included in this type. They go first in the C struct.
|
||||||
of the new struct's dictionary in the Client JSON Protocol wire
|
|
||||||
format. An example definition is:
|
|
||||||
|
|
||||||
{ 'struct': 'BlockdevOptionsGenericFormat', 'data': { 'file': 'str' } }
|
Example:
|
||||||
|
|
||||||
|
{ 'struct': 'BlockdevOptionsGenericFormat',
|
||||||
|
'data': { 'file': 'str' } }
|
||||||
{ 'struct': 'BlockdevOptionsGenericCOWFormat',
|
{ 'struct': 'BlockdevOptionsGenericCOWFormat',
|
||||||
'base': 'BlockdevOptionsGenericFormat',
|
'base': 'BlockdevOptionsGenericFormat',
|
||||||
'data': { '*backing': 'str' } }
|
'data': { '*backing': 'str' } }
|
||||||
|
@ -205,18 +267,40 @@ both members like this:
|
||||||
{ "file": "/some/place/my-image",
|
{ "file": "/some/place/my-image",
|
||||||
"backing": "/some/place/my-backing-file" }
|
"backing": "/some/place/my-backing-file" }
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
=== Union types ===
|
=== Union types ===
|
||||||
|
|
||||||
Usage: { 'union': STRING, 'data': DICT }
|
Syntax:
|
||||||
or: { 'union': STRING, 'data': DICT, 'base': STRUCT-NAME-OR-DICT,
|
UNION = { 'union': STRING,
|
||||||
'discriminator': ENUM-MEMBER-OF-BASE }
|
'data': BRANCHES,
|
||||||
|
'*if': COND }
|
||||||
|
| { 'union': STRING,
|
||||||
|
'data': BRANCHES,
|
||||||
|
'base': ( MEMBERS | STRING ),
|
||||||
|
'discriminator': STRING,
|
||||||
|
'*if': COND }
|
||||||
|
BRANCHES = { BRANCH, ... }
|
||||||
|
BRANCH = STRING : TYPE-REF
|
||||||
|
| STRING : { 'type': TYPE-REF, '*if': COND }
|
||||||
|
|
||||||
Union types are used to let the user choose between several different
|
Member 'union' names the union type.
|
||||||
variants for an object. There are two flavors: simple (no
|
|
||||||
discriminator or base), and flat (both discriminator and base). A union
|
There are two flavors of union types: simple (no discriminator or
|
||||||
type is defined using a data dictionary as explained in the following
|
base), and flat (both discriminator and base).
|
||||||
paragraphs. Unions must have at least one branch.
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The BRANCH's value defines the branch's properties, in particular its
|
||||||
|
type. The form TYPE-REF is shorthand for { 'type': TYPE-REF }.
|
||||||
|
|
||||||
A simple union type defines a mapping from automatic discriminator
|
A simple union type defines a mapping from automatic discriminator
|
||||||
values to data types like in this example:
|
values to data types like in this example:
|
||||||
|
@ -229,8 +313,8 @@ values to data types like in this example:
|
||||||
'data': { 'file': 'BlockdevOptionsFile',
|
'data': { 'file': 'BlockdevOptionsFile',
|
||||||
'qcow2': 'BlockdevOptionsQcow2' } }
|
'qcow2': 'BlockdevOptionsQcow2' } }
|
||||||
|
|
||||||
In the Client JSON Protocol, a simple union is represented by a
|
In the Client JSON Protocol, a simple union is represented by an
|
||||||
dictionary that contains the 'type' member as a discriminator, and a
|
object that contains the 'type' member as a discriminator, and a
|
||||||
'data' member that is of the specified data type corresponding to the
|
'data' member that is of the specified data type corresponding to the
|
||||||
discriminator value, as in these examples:
|
discriminator value, as in these examples:
|
||||||
|
|
||||||
|
@ -238,21 +322,27 @@ discriminator value, as in these examples:
|
||||||
{ "type": "qcow2", "data": { "backing": "/some/place/my-image",
|
{ "type": "qcow2", "data": { "backing": "/some/place/my-image",
|
||||||
"lazy-refcounts": true } }
|
"lazy-refcounts": true } }
|
||||||
|
|
||||||
The generated C code uses a struct containing a union. Additionally,
|
The generated C code uses a struct containing a union. Additionally,
|
||||||
an implicit C enum 'NameKind' is created, corresponding to the union
|
an implicit C enum 'NameKind' is created, corresponding to the union
|
||||||
'Name', for accessing the various branches of the union. The value
|
'Name', for accessing the various branches of the union. The value
|
||||||
for each branch can be of any type.
|
for each branch can be of any type.
|
||||||
|
|
||||||
A flat union definition avoids nesting on the wire, and specifies a
|
Flat unions permit arbitrary common members that occur in all variants
|
||||||
set of common members that occur in all variants of the union. The
|
of the union, not just a discriminator. Their discriminators need not
|
||||||
'base' key must specify either a type name (the type must be a
|
be named 'type'. They also avoid nesting on the wire.
|
||||||
struct, not a union), or a dictionary representing an anonymous type.
|
|
||||||
All branches of the union must be struct types, and the top-level
|
The 'base' member defines the common members. If it is a MEMBERS
|
||||||
members of the union dictionary on the wire will be combination of
|
object, it defines common members just like a struct type's 'data'
|
||||||
members from both the base type and the appropriate branch type (when
|
member defines struct type members. If it is a STRING, it names a
|
||||||
merging two dictionaries, there must be no keys in common). The
|
struct type whose members are the common members.
|
||||||
'discriminator' member must be the name of a non-optional enum-typed
|
|
||||||
member of the base struct.
|
All flat union branches must be of struct type.
|
||||||
|
|
||||||
|
In the Client JSON Protocol, a flat 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. Member
|
||||||
|
'discriminator' must name a non-optional enum-typed member of the base
|
||||||
|
struct.
|
||||||
|
|
||||||
The following example enhances the above simple union example by
|
The following example enhances the above simple union example by
|
||||||
adding an optional common member 'read-only', renaming the
|
adding an optional common member 'read-only', renaming the
|
||||||
|
@ -276,12 +366,13 @@ Resulting in these JSON objects:
|
||||||
Notice that in a flat union, the discriminator name is controlled by
|
Notice that in a flat union, the discriminator name is controlled by
|
||||||
the user, but because it must map to a base member with enum type, the
|
the user, but because it must map to a base member with enum type, the
|
||||||
code generator ensures that branches match the existing values of the
|
code generator ensures that branches match the existing values of the
|
||||||
enum. The order of the keys need not match the declaration of the enum.
|
enum. The order of branches need not match the order of the enum
|
||||||
The keys need not cover all possible enum values. Omitted enum values
|
values. The branches need not cover all possible enum values.
|
||||||
are still valid branches that add no additional members to the data type.
|
Omitted enum values are still valid branches that add no additional
|
||||||
In the resulting generated C data types, a flat union is
|
members to the data type. In the resulting generated C data types, a
|
||||||
represented as a struct with the base members included directly, and
|
flat union is represented as a struct with the base members in QAPI
|
||||||
then a union of structures for each branch of the struct.
|
schema order, and then a union of structures for each branch of the
|
||||||
|
struct.
|
||||||
|
|
||||||
A simple union can always be re-written as a flat union where the base
|
A simple union can always be re-written as a flat union where the base
|
||||||
class has a single member named 'type', and where each branch of the
|
class has a single member named 'type', and where each branch of the
|
||||||
|
@ -297,32 +388,47 @@ is identical on the wire to:
|
||||||
{ 'union': 'Flat': 'base': { 'type': 'Enum' }, 'discriminator': 'type',
|
{ 'union': 'Flat': 'base': { 'type': 'Enum' }, 'discriminator': 'type',
|
||||||
'data': { 'one': 'Branch1', 'two': 'Branch2' } }
|
'data': { 'one': 'Branch1', 'two': 'Branch2' } }
|
||||||
|
|
||||||
|
The optional 'if' member specifies a conditional. See "Configuring
|
||||||
|
the schema" below for more on this.
|
||||||
|
|
||||||
|
|
||||||
=== Alternate types ===
|
=== Alternate types ===
|
||||||
|
|
||||||
Usage: { 'alternate': STRING, 'data': DICT }
|
Syntax:
|
||||||
|
ALTERNATE = { 'alternate': STRING,
|
||||||
|
'data': ALTERNATIVES,
|
||||||
|
'*if': COND }
|
||||||
|
ALTERNATIVES = { ALTERNATIVE, ... }
|
||||||
|
ALTERNATIVE = STRING : TYPE-REF
|
||||||
|
| STRING : { 'type': STRING, '*if': COND }
|
||||||
|
|
||||||
An alternate type is one that allows a choice between two or more JSON
|
Member 'alternate' names the alternate type.
|
||||||
data types (string, integer, number, or object, but currently not
|
|
||||||
array) on the wire. The definition is similar to a simple union type,
|
Each ALTERNATIVE of the 'data' object defines a branch of the
|
||||||
where each branch of the union names a QAPI type. For example:
|
alternate. An alternate must have at least one branch.
|
||||||
|
|
||||||
|
The ALTERNATIVE's STRING name is the branch name.
|
||||||
|
|
||||||
|
The ALTERNATIVE's value defines the branch's properties, in particular
|
||||||
|
its type. The form STRING is shorthand for { 'type': STRING }.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
{ 'alternate': 'BlockdevRef',
|
{ 'alternate': 'BlockdevRef',
|
||||||
'data': { 'definition': 'BlockdevOptions',
|
'data': { 'definition': 'BlockdevOptions',
|
||||||
'reference': 'str' } }
|
'reference': 'str' } }
|
||||||
|
|
||||||
Unlike a union, the discriminator string is never passed on the wire
|
An alternate type is like a union type, except there is no
|
||||||
for the Client JSON Protocol. Instead, the value's JSON type serves
|
discriminator on the wire. Instead, the branch to use is inferred
|
||||||
as an implicit discriminator, which in turn means that an alternate
|
from the value. An alternate can only express a choice between types
|
||||||
can only express a choice between types represented differently in
|
represented differently on the wire.
|
||||||
JSON. If a branch is typed as the 'bool' built-in, the alternate
|
|
||||||
accepts true and false; if it is typed as any of the various numeric
|
If a branch is typed as the 'bool' built-in, the alternate accepts
|
||||||
|
true and false; if it is typed as any of the various numeric
|
||||||
built-ins, it accepts a JSON number; if it is typed as a 'str'
|
built-ins, it accepts a JSON number; if it is typed as a 'str'
|
||||||
built-in or named enum type, it accepts a JSON string; if it is typed
|
built-in or named enum type, it accepts a JSON string; if it is typed
|
||||||
as the 'null' built-in, it accepts JSON null; and if it is typed as a
|
as the 'null' built-in, it accepts JSON null; and if it is typed as a
|
||||||
complex type (struct or union), it accepts a JSON object. Two
|
complex type (struct or union), it accepts a JSON object.
|
||||||
different complex types, for instance, aren't permitted, because both
|
|
||||||
are represented as a JSON object.
|
|
||||||
|
|
||||||
The example alternate declaration above allows using both of the
|
The example alternate declaration above allows using both of the
|
||||||
following example objects:
|
following example objects:
|
||||||
|
@ -332,43 +438,52 @@ following example objects:
|
||||||
"read-only": false,
|
"read-only": false,
|
||||||
"filename": "/tmp/mydisk.qcow2" } }
|
"filename": "/tmp/mydisk.qcow2" } }
|
||||||
|
|
||||||
|
The optional 'if' member specifies a conditional. See "Configuring
|
||||||
|
the schema" below for more on this.
|
||||||
|
|
||||||
|
|
||||||
=== Commands ===
|
=== Commands ===
|
||||||
|
|
||||||
--- General Command Layout ---
|
Syntax:
|
||||||
|
COMMAND = { 'command': STRING,
|
||||||
|
(
|
||||||
|
'*data': ( MEMBERS | STRING ),
|
||||||
|
|
|
||||||
|
'data': STRING,
|
||||||
|
'boxed': true,
|
||||||
|
)
|
||||||
|
'*returns': TYPE-REF,
|
||||||
|
'*success-response': false,
|
||||||
|
'*gen': false,
|
||||||
|
'*allow-oob': true,
|
||||||
|
'*allow-preconfig': true,
|
||||||
|
'*if': COND }
|
||||||
|
|
||||||
Usage: { 'command': STRING, '*data': COMPLEX-TYPE-NAME-OR-DICT,
|
Member 'command' names the command.
|
||||||
'*returns': TYPE-NAME, '*boxed': true,
|
|
||||||
'*gen': false, '*success-response': false,
|
|
||||||
'*allow-oob': true, '*allow-preconfig': true }
|
|
||||||
|
|
||||||
Commands are defined by using a dictionary containing several members,
|
Member 'data' defines the arguments. It defaults to an empty MEMBERS
|
||||||
where three members are most common. The 'command' member is a
|
object.
|
||||||
mandatory string, and determines the "execute" value passed in a
|
|
||||||
Client JSON Protocol command exchange.
|
|
||||||
|
|
||||||
The 'data' argument maps to the "arguments" dictionary passed in as
|
If 'data' is a MEMBERS object, then MEMBERS defines arguments just
|
||||||
part of a Client JSON Protocol command. The 'data' member is optional
|
like a struct type's 'data' defines struct type members.
|
||||||
and defaults to {} (an empty dictionary). If present, it must be the
|
|
||||||
string name of a complex type, or a dictionary that declares an
|
|
||||||
anonymous type with the same semantics as a 'struct' expression.
|
|
||||||
|
|
||||||
The 'returns' member describes what will appear in the "return" member
|
If 'data' is a STRING, then STRING names a complex type whose members
|
||||||
of a Client JSON Protocol reply on successful completion of a command.
|
are the arguments. A union type requires 'boxed': true.
|
||||||
The member is optional from the command declaration; if absent, the
|
|
||||||
"return" member will be an empty dictionary. If 'returns' is present,
|
Member 'returns' defines the command's return type. It defaults to an
|
||||||
it must be the string name of a complex type, or a
|
empty struct type. It must normally be a complex type or an array of
|
||||||
one-element array containing the name of a complex type.
|
a complex type. To return anything else, the command must be listed
|
||||||
To return anything else, you have to list the command in pragma
|
in pragma 'returns-whitelist'. If you do this, extending the command
|
||||||
'returns-whitelist'. If you do this, the command cannot be extended
|
to return additional information will be harder. Use of
|
||||||
to return additional information in the future. Use of
|
|
||||||
'returns-whitelist' for new commands is strongly discouraged.
|
'returns-whitelist' for new commands is strongly discouraged.
|
||||||
|
|
||||||
All commands in Client JSON Protocol use a dictionary to report
|
A command's error responses are not specified in the QAPI schema.
|
||||||
failure, with no way to specify that in QAPI. Where the error return
|
Error conditions should be documented in comments.
|
||||||
is different than the usual GenericError class in order to help the
|
|
||||||
client react differently to certain error conditions, it is worth
|
In the Client JSON Protocol, the value of the "execute" or "exec-oob"
|
||||||
documenting this in the comments before the command declaration.
|
member is the command name. The value of the "arguments" member then
|
||||||
|
has to conform to the arguments, and the value of the success
|
||||||
|
response's "return" member will conform to the return type.
|
||||||
|
|
||||||
Some example commands:
|
Some example commands:
|
||||||
|
|
||||||
|
@ -386,23 +501,24 @@ which would validate this Client JSON Protocol transaction:
|
||||||
=> { "execute": "my-second-command" }
|
=> { "execute": "my-second-command" }
|
||||||
<= { "return": [ { "value": "one" }, { } ] }
|
<= { "return": [ { "value": "one" }, { } ] }
|
||||||
|
|
||||||
The generator emits a prototype for the user's function implementing
|
The generator emits a prototype for the C function implementing the
|
||||||
the command. Normally, 'data' is a dictionary for an anonymous type,
|
command. The function itself needs to be written by hand. See
|
||||||
or names a struct type (possibly empty, but not a union), and its
|
section "Code generated for commands" for examples.
|
||||||
members are passed as separate arguments to this function. If the
|
|
||||||
command definition includes a key 'boxed' with the boolean value true,
|
The function returns the return type. When member 'boxed' is absent,
|
||||||
then 'data' is instead the name of any non-empty complex type (struct
|
it takes the command arguments as arguments one by one, in QAPI schema
|
||||||
or union), and a pointer to that QAPI type is passed as a single
|
order. Else it takes them wrapped in the C struct generated for the
|
||||||
argument.
|
complex argument type. It takes an additional Error ** argument in
|
||||||
|
either case.
|
||||||
|
|
||||||
The generator also emits a marshalling function that extracts
|
The generator also emits a marshalling function that extracts
|
||||||
arguments for the user's function out of an input QDict, calls the
|
arguments for the user's function out of an input QDict, calls the
|
||||||
user's function, and if it succeeded, builds an output QObject from
|
user's function, and if it succeeded, builds an output QObject from
|
||||||
its return value.
|
its return value. This is for use by the QMP monitor core.
|
||||||
|
|
||||||
In rare cases, QAPI cannot express a type-safe representation of a
|
In rare cases, QAPI cannot express a type-safe representation of a
|
||||||
corresponding Client JSON Protocol command. You then have to suppress
|
corresponding Client JSON Protocol command. You then have to suppress
|
||||||
generation of a marshalling function by including a key 'gen' with
|
generation of a marshalling function by including a member 'gen' with
|
||||||
boolean value false, and instead write your own function. For
|
boolean value false, and instead write your own function. For
|
||||||
example:
|
example:
|
||||||
|
|
||||||
|
@ -416,13 +532,12 @@ use type-safe unions.
|
||||||
Normally, the QAPI schema is used to describe synchronous exchanges,
|
Normally, the QAPI schema is used to describe synchronous exchanges,
|
||||||
where a response is expected. But in some cases, the action of a
|
where a response is expected. But in some cases, the action of a
|
||||||
command is expected to change state in a way that a successful
|
command is expected to change state in a way that a successful
|
||||||
response is not possible (although the command will still return a
|
response is not possible (although the command will still return an
|
||||||
normal dictionary error on failure). When a successful reply is not
|
error object on failure). When a successful reply is not possible,
|
||||||
possible, the command expression includes the optional key
|
the command definition includes the optional member 'success-response'
|
||||||
'success-response' with boolean value false. So far, only QGA makes
|
with boolean value false. So far, only QGA makes use of this member.
|
||||||
use of this member.
|
|
||||||
|
|
||||||
Key 'allow-oob' declares whether the command supports out-of-band
|
Member 'allow-oob' declares whether the command supports out-of-band
|
||||||
(OOB) execution. It defaults to false. For example:
|
(OOB) execution. It defaults to false. For example:
|
||||||
|
|
||||||
{ 'command': 'migrate_recover',
|
{ 'command': 'migrate_recover',
|
||||||
|
@ -455,8 +570,8 @@ other "slow" lock.
|
||||||
|
|
||||||
When in doubt, do not implement OOB execution support.
|
When in doubt, do not implement OOB execution support.
|
||||||
|
|
||||||
Key 'allow-preconfig' declares whether the command is available before
|
Member 'allow-preconfig' declares whether the command is available
|
||||||
the machine is built. It defaults to false. For example:
|
before the machine is built. It defaults to false. For example:
|
||||||
|
|
||||||
{ 'command': 'qmp_capabilities',
|
{ 'command': 'qmp_capabilities',
|
||||||
'data': { '*enable': [ 'QMPCapability' ] },
|
'data': { '*enable': [ 'QMPCapability' ] },
|
||||||
|
@ -465,16 +580,33 @@ the machine is built. It defaults to false. For example:
|
||||||
QMP is available before the machine is built only when QEMU was
|
QMP is available before the machine is built only when QEMU was
|
||||||
started with --preconfig.
|
started with --preconfig.
|
||||||
|
|
||||||
|
The optional 'if' member specifies a conditional. See "Configuring
|
||||||
|
the schema" below for more on this.
|
||||||
|
|
||||||
|
|
||||||
=== Events ===
|
=== Events ===
|
||||||
|
|
||||||
Usage: { 'event': STRING, '*data': COMPLEX-TYPE-NAME-OR-DICT,
|
Syntax:
|
||||||
'*boxed': true }
|
EVENT = { 'event': STRING,
|
||||||
|
(
|
||||||
|
'*data': ( MEMBERS | STRING ),
|
||||||
|
|
|
||||||
|
'data': STRING,
|
||||||
|
'boxed': true,
|
||||||
|
)
|
||||||
|
'*if': COND }
|
||||||
|
|
||||||
Events are defined with the keyword 'event'. When 'data' is also
|
Member 'event' names the event. This is the event name used in the
|
||||||
specified, additional info will be included in the event, with similar
|
Client JSON Protocol.
|
||||||
semantics to a 'struct' expression. Finally there will be C API
|
|
||||||
generated in qapi-events.h; when called by QEMU code, a message with
|
Member 'data' defines the event-specific data. It defaults to an
|
||||||
timestamp will be emitted on the wire.
|
empty MEMBERS object.
|
||||||
|
|
||||||
|
If 'data' is a MEMBERS object, then MEMBERS defines event-specific
|
||||||
|
data just like a struct type's 'data' defines struct type members.
|
||||||
|
|
||||||
|
If 'data' is a STRING, then STRING names a complex type whose members
|
||||||
|
are the event-specific data. A union type requires 'boxed': true.
|
||||||
|
|
||||||
An example event is:
|
An example event is:
|
||||||
|
|
||||||
|
@ -487,42 +619,44 @@ Resulting in this JSON object:
|
||||||
"data": { "b": "test string" },
|
"data": { "b": "test string" },
|
||||||
"timestamp": { "seconds": 1267020223, "microseconds": 435656 } }
|
"timestamp": { "seconds": 1267020223, "microseconds": 435656 } }
|
||||||
|
|
||||||
The generator emits a function to send the event. Normally, 'data' is
|
The generator emits a function to send the event. When member 'boxed'
|
||||||
a dictionary for an anonymous type, or names a struct type (possibly
|
is absent, it takes event-specific data one by one, in QAPI schema
|
||||||
empty, but not a union), and its members are passed as separate
|
order. Else it takes them wrapped in the C struct generated for the
|
||||||
arguments to this function. If the event definition includes a key
|
complex type. See section "Code generated for events" for examples.
|
||||||
'boxed' with the boolean value true, then 'data' is instead the name
|
|
||||||
of any non-empty complex type (struct or union), and a pointer to that
|
The optional 'if' member specifies a conditional. See "Configuring
|
||||||
QAPI type is passed as a single argument.
|
the schema" below for more on this.
|
||||||
|
|
||||||
|
|
||||||
=== Features ===
|
=== Features ===
|
||||||
|
|
||||||
|
Syntax:
|
||||||
|
FEATURES = [ FEATURE, ... ]
|
||||||
|
FEATURE = STRING
|
||||||
|
| { 'name': STRING, '*if': COND }
|
||||||
|
|
||||||
Sometimes, the behaviour of QEMU changes compatibly, but without a
|
Sometimes, the behaviour of QEMU changes compatibly, but without a
|
||||||
change in the QMP syntax (usually by allowing values or operations that
|
change in the QMP syntax (usually by allowing values or operations
|
||||||
previously resulted in an error). QMP clients may still need to know
|
that previously resulted in an error). QMP clients may still need to
|
||||||
whether the extension is available.
|
know whether the extension is available.
|
||||||
|
|
||||||
For this purpose, a list of features can be specified for a struct type.
|
For this purpose, a list of features can be specified for a struct type.
|
||||||
This is exposed to the client as a list of string, where each string
|
This is exposed to the client as a list of string, where each string
|
||||||
signals that this build of QEMU shows a certain behaviour.
|
signals that this build of QEMU shows a certain behaviour.
|
||||||
|
|
||||||
In the schema, features can be specified as simple strings, for example:
|
Each member of the 'features' array defines a feature. It can either
|
||||||
|
be { 'name': STRING, '*if': COND }, or STRING, which is shorthand for
|
||||||
|
{ 'name': STRING }.
|
||||||
|
|
||||||
|
The optional 'if' member specifies a conditional. See "Configuring
|
||||||
|
the schema" below for more on this.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
{ 'struct': 'TestType',
|
{ 'struct': 'TestType',
|
||||||
'data': { 'number': 'int' },
|
'data': { 'number': 'int' },
|
||||||
'features': [ 'allow-negative-numbers' ] }
|
'features': [ 'allow-negative-numbers' ] }
|
||||||
|
|
||||||
Another option is to specify features as dictionaries, where the key
|
|
||||||
'name' specifies the feature string to be exposed to clients:
|
|
||||||
|
|
||||||
{ 'struct': 'TestType',
|
|
||||||
'data': { 'number': 'int' },
|
|
||||||
'features': [ { 'name': 'allow-negative-numbers' } ] }
|
|
||||||
|
|
||||||
This expanded form is necessary if you want to make the feature
|
|
||||||
conditional (see below in "Configuring the schema").
|
|
||||||
|
|
||||||
|
|
||||||
=== Naming rules and reserved names ===
|
=== Naming rules and reserved names ===
|
||||||
|
|
||||||
|
@ -546,9 +680,8 @@ respectively.
|
||||||
|
|
||||||
Command names, and member names within a type, should be all lower
|
Command names, and member names within a type, should be all lower
|
||||||
case with words separated by a hyphen. However, some existing older
|
case with words separated by a hyphen. However, some existing older
|
||||||
commands and complex types use underscore; when extending such
|
commands and complex types use underscore; when extending them,
|
||||||
expressions, consistency is preferred over blindly avoiding
|
consistency is preferred over blindly avoiding underscore.
|
||||||
underscore.
|
|
||||||
|
|
||||||
Event names should be ALL_CAPS with words separated by underscore.
|
Event names should be ALL_CAPS with words separated by underscore.
|
||||||
|
|
||||||
|
@ -578,11 +711,14 @@ downstream command __com.redhat_drive-mirror.
|
||||||
|
|
||||||
=== Configuring the schema ===
|
=== Configuring the schema ===
|
||||||
|
|
||||||
The 'struct', 'enum', 'union', 'alternate', 'command' and 'event'
|
Syntax:
|
||||||
top-level expressions can take an 'if' key. Its value must be a string
|
COND = STRING
|
||||||
or a list of strings. A string is shorthand for a list containing just
|
| [ STRING, ... ]
|
||||||
that string. The code generated for the top-level expression will then
|
|
||||||
be guarded by #if COND for each COND in the list.
|
All definitions take an optional 'if' member. Its value must be a
|
||||||
|
string or a list of strings. A string is shorthand for a list
|
||||||
|
containing just that string. The code generated for the definition
|
||||||
|
will then be guarded by #if STRING for each STRING in the COND list.
|
||||||
|
|
||||||
Example: a conditional struct
|
Example: a conditional struct
|
||||||
|
|
||||||
|
@ -597,29 +733,33 @@ gets its generated code guarded like this:
|
||||||
#endif /* defined(HAVE_BAR) */
|
#endif /* defined(HAVE_BAR) */
|
||||||
#endif /* defined(CONFIG_FOO) */
|
#endif /* defined(CONFIG_FOO) */
|
||||||
|
|
||||||
Where a member can be defined with a single string value for its type,
|
Individual members of complex types, commands arguments, and
|
||||||
it is also possible to supply a dictionary instead with both 'type'
|
event-specific data can also be made conditional. This requires the
|
||||||
and 'if' keys.
|
longhand form of MEMBER.
|
||||||
|
|
||||||
Example: a conditional 'bar' member
|
Example: a struct type with unconditional member 'foo' and conditional
|
||||||
|
member 'bar'
|
||||||
|
|
||||||
{ 'struct': 'IfStruct', 'data':
|
{ 'struct': 'IfStruct', 'data':
|
||||||
{ 'foo': 'int',
|
{ 'foo': 'int',
|
||||||
'bar': { 'type': 'int', 'if': 'defined(IFCOND)'} } }
|
'bar': { 'type': 'int', 'if': 'defined(IFCOND)'} } }
|
||||||
|
|
||||||
An enum value can be replaced by a dictionary with a 'name' and a 'if'
|
A union's discriminator may not be conditional.
|
||||||
key.
|
|
||||||
|
|
||||||
Example: a conditional 'bar' enum member.
|
Likewise, individual enumeration values be conditional. This requires
|
||||||
|
the longhand form of ENUM-VALUE.
|
||||||
|
|
||||||
|
Example: an enum type with unconditional value 'foo' and conditional
|
||||||
|
value 'bar'
|
||||||
|
|
||||||
{ 'enum': 'IfEnum', 'data':
|
{ 'enum': 'IfEnum', 'data':
|
||||||
[ 'foo',
|
[ 'foo',
|
||||||
{ 'name' : 'bar', 'if': 'defined(IFCOND)' } ] }
|
{ 'name' : 'bar', 'if': 'defined(IFCOND)' } ] }
|
||||||
|
|
||||||
Similarly, features can be specified as a dictionary with a 'name' and
|
Likewise, features can be conditional. This requires the longhand
|
||||||
an 'if' key.
|
form of FEATURE.
|
||||||
|
|
||||||
Example: a conditional 'allow-negative-numbers' feature
|
Example: a struct with conditional feature 'allow-negative-numbers'
|
||||||
|
|
||||||
{ 'struct': 'TestType',
|
{ 'struct': 'TestType',
|
||||||
'data': { 'number': 'int' },
|
'data': { 'number': 'int' },
|
||||||
|
@ -628,17 +768,30 @@ Example: a conditional 'allow-negative-numbers' feature
|
||||||
|
|
||||||
Please note that you are responsible to ensure that the C code will
|
Please note that you are responsible to ensure that the C code will
|
||||||
compile with an arbitrary combination of conditions, since the
|
compile with an arbitrary combination of conditions, since the
|
||||||
generators are unable to check it at this point.
|
generator is unable to check it at this point.
|
||||||
|
|
||||||
The presence of 'if' keys in the schema is reflected through to the
|
The conditions apply to introspection as well, i.e. introspection
|
||||||
introspection output depending on the build configuration.
|
shows a conditional entity only when the condition is satisfied in
|
||||||
|
this particular build.
|
||||||
|
|
||||||
|
|
||||||
=== Documentation comments ===
|
=== Documentation comments ===
|
||||||
|
|
||||||
A multi-line comment that starts and ends with a '##' line is a
|
A multi-line comment that starts and ends with a '##' line is a
|
||||||
documentation comment. These are parsed by the documentation
|
documentation comment.
|
||||||
generator, which recognizes certain markup detailed below.
|
|
||||||
|
If the documentation comment starts like
|
||||||
|
|
||||||
|
##
|
||||||
|
# @SYMBOL:
|
||||||
|
|
||||||
|
it documents the definition if SYMBOL, else it's free-form
|
||||||
|
documentation.
|
||||||
|
|
||||||
|
See below for more on definition documentation.
|
||||||
|
|
||||||
|
Free-form documentation may be used to provide additional text and
|
||||||
|
structuring content.
|
||||||
|
|
||||||
|
|
||||||
==== Documentation markup ====
|
==== Documentation markup ====
|
||||||
|
@ -701,23 +854,24 @@ Example:
|
||||||
##
|
##
|
||||||
|
|
||||||
|
|
||||||
==== Expression documentation ====
|
==== Definition documentation ====
|
||||||
|
|
||||||
Expressions other than include and pragma directives may be preceded
|
Definition documentation, if present, must immediately precede the
|
||||||
by a documentation block. Such blocks are called expression
|
definition it documents.
|
||||||
documentation blocks.
|
|
||||||
|
|
||||||
When documentation is required (see pragma 'doc-required'), expression
|
When documentation is required (see pragma 'doc-required'), every
|
||||||
documentation blocks are mandatory.
|
definition must have documentation.
|
||||||
|
|
||||||
The documentation block consists of a first line naming the
|
Definition documentation starts with a line naming the definition,
|
||||||
expression, an optional overview, a description of each argument (for
|
followed by an optional overview, a description of each argument (for
|
||||||
commands and events) or member (for structs, unions and alternates),
|
commands and events), member (for structs and unions), branch (for
|
||||||
and optional tagged sections.
|
alternates), or value (for enums), and finally optional tagged
|
||||||
|
sections.
|
||||||
|
|
||||||
FIXME: the parser accepts these things in almost any order.
|
FIXME: the parser accepts these things in almost any order.
|
||||||
|
FIXME: union branches should be described, too.
|
||||||
|
|
||||||
Extensions added after the expression was first released carry a
|
Extensions added after the definition was first released carry a
|
||||||
'(since x.y.z)' comment.
|
'(since x.y.z)' comment.
|
||||||
|
|
||||||
A tagged section starts with one of the following words:
|
A tagged section starts with one of the following words:
|
||||||
|
@ -725,7 +879,7 @@ A tagged section starts with one of the following words:
|
||||||
The section ends with the start of a new section.
|
The section ends with the start of a new section.
|
||||||
|
|
||||||
A 'Since: x.y.z' tagged section lists the release that introduced the
|
A 'Since: x.y.z' tagged section lists the release that introduced the
|
||||||
expression.
|
definition.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
|
@ -771,12 +925,6 @@ For example:
|
||||||
'data': { '*query-nodes': 'bool' },
|
'data': { '*query-nodes': 'bool' },
|
||||||
'returns': ['BlockStats'] }
|
'returns': ['BlockStats'] }
|
||||||
|
|
||||||
==== Free-form documentation ====
|
|
||||||
|
|
||||||
A documentation block that isn't an expression documentation block is
|
|
||||||
a free-form documentation block. These may be used to provide
|
|
||||||
additional text and structuring content.
|
|
||||||
|
|
||||||
|
|
||||||
== Client JSON Protocol introspection ==
|
== Client JSON Protocol introspection ==
|
||||||
|
|
||||||
|
@ -862,7 +1010,7 @@ If the event carries no additional information, "arg-type" names an
|
||||||
object type without members. The event may not have a data member on
|
object type without members. The event may not have a data member on
|
||||||
the wire then.
|
the wire then.
|
||||||
|
|
||||||
Each command or event defined with dictionary-valued 'data' in the
|
Each command or event defined with 'data' as MEMBERS object in the
|
||||||
QAPI schema implicitly defines an object type.
|
QAPI schema implicitly defines an object type.
|
||||||
|
|
||||||
Example: the SchemaInfo for EVENT_C from section Events
|
Example: the SchemaInfo for EVENT_C from section Events
|
||||||
|
@ -1044,7 +1192,7 @@ receive direction compatibility.
|
||||||
|
|
||||||
Any change to types used in both contexts need to consider both.
|
Any change to types used in both contexts need to consider both.
|
||||||
|
|
||||||
Members of enumeration types, complex types and alternate types may be
|
Enumeration type values and complex and alternate type members may be
|
||||||
reordered freely. For enumerations and alternate types, this doesn't
|
reordered freely. For enumerations and alternate types, this doesn't
|
||||||
affect the wire encoding. For complex types, this might make the
|
affect the wire encoding. For complex types, this might make the
|
||||||
implementation emit JSON object members in a different order, which
|
implementation emit JSON object members in a different order, which
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue