aboutsummaryrefslogtreecommitdiff
path: root/scripts/qapi
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/qapi')
-rw-r--r--scripts/qapi/commands.py2
-rw-r--r--scripts/qapi/events.py2
-rw-r--r--scripts/qapi/gen.py2
-rw-r--r--scripts/qapi/introspect.py15
-rw-r--r--scripts/qapi/schema.py225
-rw-r--r--scripts/qapi/types.py12
-rw-r--r--scripts/qapi/visit.py24
7 files changed, 148 insertions, 134 deletions
diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py
index d1fdf41..79951a8 100644
--- a/scripts/qapi/commands.py
+++ b/scripts/qapi/commands.py
@@ -64,7 +64,7 @@ def gen_call(name: str,
assert arg_type
argstr = '&arg, '
elif arg_type:
- assert not arg_type.variants
+ assert not arg_type.branches
for memb in arg_type.members:
assert not memb.ifcond.is_present()
if memb.need_has():
diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py
index 3cf01e9..d1f6399 100644
--- a/scripts/qapi/events.py
+++ b/scripts/qapi/events.py
@@ -51,7 +51,7 @@ def gen_param_var(typ: QAPISchemaObjectType) -> str:
Initialize it with the function arguments defined in `gen_event_send`.
"""
- assert not typ.variants
+ assert not typ.branches
ret = mcgen('''
%(c_name)s param = {
''',
diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py
index 5412716..6a8abe0 100644
--- a/scripts/qapi/gen.py
+++ b/scripts/qapi/gen.py
@@ -118,7 +118,7 @@ def build_params(arg_type: Optional[QAPISchemaObjectType],
ret += '%s arg' % arg_type.c_param_type()
sep = ', '
elif arg_type:
- assert not arg_type.variants
+ assert not arg_type.branches
for memb in arg_type.members:
assert not memb.ifcond.is_present()
ret += sep
diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index 4679b1b..86c075a 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -26,6 +26,8 @@ from .common import c_name, mcgen
from .gen import QAPISchemaMonolithicCVisitor
from .schema import (
QAPISchema,
+ QAPISchemaAlternatives,
+ QAPISchemaBranches,
QAPISchemaArrayType,
QAPISchemaBuiltinType,
QAPISchemaEntity,
@@ -36,7 +38,6 @@ from .schema import (
QAPISchemaObjectTypeMember,
QAPISchemaType,
QAPISchemaVariant,
- QAPISchemaVariants,
)
from .source import QAPISourceInfo
@@ -335,24 +336,24 @@ const QLitObject %(c_name)s = %(c_string)s;
ifcond: QAPISchemaIfCond,
features: List[QAPISchemaFeature],
members: List[QAPISchemaObjectTypeMember],
- variants: Optional[QAPISchemaVariants]) -> None:
+ branches: Optional[QAPISchemaBranches]) -> None:
obj: SchemaInfoObject = {
'members': [self._gen_object_member(m) for m in members]
}
- if variants:
- obj['tag'] = variants.tag_member.name
- obj['variants'] = [self._gen_variant(v) for v in variants.variants]
+ if branches:
+ obj['tag'] = branches.tag_member.name
+ obj['variants'] = [self._gen_variant(v) for v in branches.variants]
self._gen_tree(name, 'object', obj, ifcond, features)
def visit_alternate_type(self, name: str, info: Optional[QAPISourceInfo],
ifcond: QAPISchemaIfCond,
features: List[QAPISchemaFeature],
- variants: QAPISchemaVariants) -> None:
+ alternatives: QAPISchemaAlternatives) -> None:
self._gen_tree(
name, 'alternate',
{'members': [Annotated({'type': self._use_type(m.type)},
m.ifcond)
- for m in variants.variants]},
+ for m in alternatives.variants]},
ifcond, features
)
diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py
index 5924947..721c470 100644
--- a/scripts/qapi/schema.py
+++ b/scripts/qapi/schema.py
@@ -215,7 +215,7 @@ class QAPISchemaVisitor:
features: List[QAPISchemaFeature],
base: Optional[QAPISchemaObjectType],
members: List[QAPISchemaObjectTypeMember],
- variants: Optional[QAPISchemaVariants],
+ branches: Optional[QAPISchemaBranches],
) -> None:
pass
@@ -226,7 +226,7 @@ class QAPISchemaVisitor:
ifcond: QAPISchemaIfCond,
features: List[QAPISchemaFeature],
members: List[QAPISchemaObjectTypeMember],
- variants: Optional[QAPISchemaVariants],
+ branches: Optional[QAPISchemaBranches],
) -> None:
pass
@@ -236,7 +236,7 @@ class QAPISchemaVisitor:
info: Optional[QAPISourceInfo],
ifcond: QAPISchemaIfCond,
features: List[QAPISchemaFeature],
- variants: QAPISchemaVariants,
+ alternatives: QAPISchemaAlternatives,
) -> None:
pass
@@ -524,20 +524,20 @@ class QAPISchemaObjectType(QAPISchemaType):
features: Optional[List[QAPISchemaFeature]],
base: Optional[str],
local_members: List[QAPISchemaObjectTypeMember],
- variants: Optional[QAPISchemaVariants],
+ branches: Optional[QAPISchemaBranches],
):
- # struct has local_members, optional base, and no variants
- # union has base, variants, and no local_members
+ # struct has local_members, optional base, and no branches
+ # union has base, branches, and no local_members
super().__init__(name, info, doc, ifcond, features)
- self.meta = 'union' if variants else 'struct'
+ self.meta = 'union' if branches else 'struct'
for m in local_members:
m.set_defined_in(name)
- if variants is not None:
- variants.set_defined_in(name)
+ if branches is not None:
+ branches.set_defined_in(name)
self._base_name = base
self.base = None
self.local_members = local_members
- self.variants = variants
+ self.branches = branches
self.members: List[QAPISchemaObjectTypeMember]
self._check_complete = False
@@ -561,7 +561,7 @@ class QAPISchemaObjectType(QAPISchemaType):
self.base = schema.resolve_type(self._base_name, self.info,
"'base'")
if (not isinstance(self.base, QAPISchemaObjectType)
- or self.base.variants):
+ or self.base.branches):
raise QAPISemError(
self.info,
"'base' requires a struct type, %s isn't"
@@ -577,9 +577,9 @@ class QAPISchemaObjectType(QAPISchemaType):
# Cast down to the subtype.
members = cast(List[QAPISchemaObjectTypeMember], list(seen.values()))
- if self.variants:
- self.variants.check(schema, seen)
- self.variants.check_clash(self.info, seen)
+ if self.branches:
+ self.branches.check(schema, seen)
+ self.branches.check_clash(self.info, seen)
self.members = members
self._check_complete = True # mark completed
@@ -595,8 +595,8 @@ class QAPISchemaObjectType(QAPISchemaType):
assert self._checked
for m in self.members:
m.check_clash(info, seen)
- if self.variants:
- self.variants.check_clash(info, seen)
+ if self.branches:
+ self.branches.check_clash(info, seen)
def connect_doc(self, doc: Optional[QAPIDoc] = None) -> None:
super().connect_doc(doc)
@@ -612,7 +612,7 @@ class QAPISchemaObjectType(QAPISchemaType):
return self.name.startswith('q_')
def is_empty(self) -> bool:
- return not self.members and not self.variants
+ return not self.members and not self.branches
def has_conditional_members(self) -> bool:
return any(m.ifcond.is_present() for m in self.members)
@@ -635,10 +635,10 @@ class QAPISchemaObjectType(QAPISchemaType):
super().visit(visitor)
visitor.visit_object_type(
self.name, self.info, self.ifcond, self.features,
- self.base, self.local_members, self.variants)
+ self.base, self.local_members, self.branches)
visitor.visit_object_type_flat(
self.name, self.info, self.ifcond, self.features,
- self.members, self.variants)
+ self.members, self.branches)
class QAPISchemaAlternateType(QAPISchemaType):
@@ -651,25 +651,25 @@ class QAPISchemaAlternateType(QAPISchemaType):
doc: Optional[QAPIDoc],
ifcond: Optional[QAPISchemaIfCond],
features: List[QAPISchemaFeature],
- variants: QAPISchemaVariants,
+ alternatives: QAPISchemaAlternatives,
):
super().__init__(name, info, doc, ifcond, features)
- assert variants.tag_member
- variants.set_defined_in(name)
- variants.tag_member.set_defined_in(self.name)
- self.variants = variants
+ assert alternatives.tag_member
+ alternatives.set_defined_in(name)
+ alternatives.tag_member.set_defined_in(self.name)
+ self.alternatives = alternatives
def check(self, schema: QAPISchema) -> None:
super().check(schema)
- self.variants.tag_member.check(schema)
- # Not calling self.variants.check_clash(), because there's nothing
- # to clash with
- self.variants.check(schema, {})
+ self.alternatives.tag_member.check(schema)
+ # Not calling self.alternatives.check_clash(), because there's
+ # nothing to clash with
+ self.alternatives.check(schema, {})
# Alternate branch names have no relation to the tag enum values;
# so we have to check for potential name collisions ourselves.
seen: Dict[str, QAPISchemaMember] = {}
types_seen: Dict[str, str] = {}
- for v in self.variants.variants:
+ for v in self.alternatives.variants:
v.check_clash(self.info, seen)
qtype = v.type.alternate_qtype()
if not qtype:
@@ -700,7 +700,7 @@ class QAPISchemaAlternateType(QAPISchemaType):
def connect_doc(self, doc: Optional[QAPIDoc] = None) -> None:
super().connect_doc(doc)
doc = doc or self.doc
- for v in self.variants.variants:
+ for v in self.alternatives.variants:
v.connect_doc(doc)
def c_type(self) -> str:
@@ -712,94 +712,86 @@ class QAPISchemaAlternateType(QAPISchemaType):
def visit(self, visitor: QAPISchemaVisitor) -> None:
super().visit(visitor)
visitor.visit_alternate_type(
- self.name, self.info, self.ifcond, self.features, self.variants)
+ self.name, self.info, self.ifcond, self.features,
+ self.alternatives)
class QAPISchemaVariants:
def __init__(
self,
- tag_name: Optional[str],
info: QAPISourceInfo,
- tag_member: Optional[QAPISchemaObjectTypeMember],
variants: List[QAPISchemaVariant],
):
- # Unions pass tag_name but not tag_member.
- # Alternates pass tag_member but not tag_name.
- # After check(), tag_member is always set.
- assert bool(tag_member) != bool(tag_name)
- assert (isinstance(tag_name, str) or
- isinstance(tag_member, QAPISchemaObjectTypeMember))
- self._tag_name = tag_name
self.info = info
- self._tag_member = tag_member
+ self.tag_member: QAPISchemaObjectTypeMember
self.variants = variants
- @property
- def tag_member(self) -> QAPISchemaObjectTypeMember:
- if self._tag_member is None:
- raise RuntimeError(
- "QAPISchemaVariants has no tag_member property until "
- "after check() has been run."
- )
- return self._tag_member
-
def set_defined_in(self, name: str) -> None:
for v in self.variants:
v.set_defined_in(name)
def check(
- self, schema: QAPISchema, seen: Dict[str, QAPISchemaMember]
+ self, schema: QAPISchema, seen: Dict[str, QAPISchemaMember]
) -> None:
- if self._tag_name: # union
- # We need to narrow the member type:
- tmp = seen.get(c_name(self._tag_name))
- assert tmp is None or isinstance(tmp, QAPISchemaObjectTypeMember)
- self._tag_member = tmp
-
- base = "'base'"
- # Pointing to the base type when not implicit would be
- # nice, but we don't know it here
- if not self._tag_member or self._tag_name != self._tag_member.name:
- raise QAPISemError(
- self.info,
- "discriminator '%s' is not a member of %s"
- % (self._tag_name, base))
- # Here we do:
- assert self.tag_member.defined_in
- base_type = schema.lookup_type(self.tag_member.defined_in)
- assert base_type
- if not base_type.is_implicit():
- base = "base type '%s'" % self.tag_member.defined_in
- if not isinstance(self.tag_member.type, QAPISchemaEnumType):
- raise QAPISemError(
- self.info,
- "discriminator member '%s' of %s must be of enum type"
- % (self._tag_name, base))
- if self.tag_member.optional:
- raise QAPISemError(
- self.info,
- "discriminator member '%s' of %s must not be optional"
- % (self._tag_name, base))
- if self.tag_member.ifcond.is_present():
- raise QAPISemError(
- self.info,
- "discriminator member '%s' of %s must not be conditional"
- % (self._tag_name, base))
- else: # alternate
- assert self._tag_member
- assert isinstance(self.tag_member.type, QAPISchemaEnumType)
- assert not self.tag_member.optional
- assert not self.tag_member.ifcond.is_present()
- if self._tag_name: # union
- # branches that are not explicitly covered get an empty type
- assert self.tag_member.defined_in
- cases = {v.name for v in self.variants}
- for m in self.tag_member.type.members:
- if m.name not in cases:
- v = QAPISchemaVariant(m.name, self.info,
- 'q_empty', m.ifcond)
- v.set_defined_in(self.tag_member.defined_in)
- self.variants.append(v)
+ for v in self.variants:
+ v.check(schema)
+
+
+class QAPISchemaBranches(QAPISchemaVariants):
+ def __init__(self,
+ info: QAPISourceInfo,
+ variants: List[QAPISchemaVariant],
+ tag_name: str):
+ super().__init__(info, variants)
+ self._tag_name = tag_name
+
+ def check(
+ self, schema: QAPISchema, seen: Dict[str, QAPISchemaMember]
+ ) -> None:
+ # We need to narrow the member type:
+ tag_member = seen.get(c_name(self._tag_name))
+ assert (tag_member is None
+ or isinstance(tag_member, QAPISchemaObjectTypeMember))
+
+ base = "'base'"
+ # Pointing to the base type when not implicit would be
+ # nice, but we don't know it here
+ if not tag_member or self._tag_name != tag_member.name:
+ raise QAPISemError(
+ self.info,
+ "discriminator '%s' is not a member of %s"
+ % (self._tag_name, base))
+ self.tag_member = tag_member
+ # Here we do:
+ assert tag_member.defined_in
+ base_type = schema.lookup_type(tag_member.defined_in)
+ assert base_type
+ if not base_type.is_implicit():
+ base = "base type '%s'" % tag_member.defined_in
+ if not isinstance(tag_member.type, QAPISchemaEnumType):
+ raise QAPISemError(
+ self.info,
+ "discriminator member '%s' of %s must be of enum type"
+ % (self._tag_name, base))
+ if tag_member.optional:
+ raise QAPISemError(
+ self.info,
+ "discriminator member '%s' of %s must not be optional"
+ % (self._tag_name, base))
+ if tag_member.ifcond.is_present():
+ raise QAPISemError(
+ self.info,
+ "discriminator member '%s' of %s must not be conditional"
+ % (self._tag_name, base))
+ # branches that are not explicitly covered get an empty type
+ assert tag_member.defined_in
+ cases = {v.name for v in self.variants}
+ for m in tag_member.type.members:
+ if m.name not in cases:
+ v = QAPISchemaVariant(m.name, self.info,
+ 'q_empty', m.ifcond)
+ v.set_defined_in(tag_member.defined_in)
+ self.variants.append(v)
if not self.variants:
raise QAPISemError(self.info, "union has no branches")
for v in self.variants:
@@ -807,11 +799,11 @@ class QAPISchemaVariants:
# Union names must match enum values; alternate names are
# checked separately. Use 'seen' to tell the two apart.
if seen:
- if v.name not in self.tag_member.type.member_names():
+ if v.name not in tag_member.type.member_names():
raise QAPISemError(
self.info,
"branch '%s' is not a value of %s"
- % (v.name, self.tag_member.type.describe()))
+ % (v.name, tag_member.type.describe()))
if not isinstance(v.type, QAPISchemaObjectType):
raise QAPISemError(
self.info,
@@ -833,6 +825,23 @@ class QAPISchemaVariants:
v.type.check_clash(info, dict(seen))
+class QAPISchemaAlternatives(QAPISchemaVariants):
+ def __init__(self,
+ info: QAPISourceInfo,
+ variants: List[QAPISchemaVariant],
+ tag_member: QAPISchemaObjectTypeMember):
+ super().__init__(info, variants)
+ self.tag_member = tag_member
+
+ def check(
+ self, schema: QAPISchema, seen: Dict[str, QAPISchemaMember]
+ ) -> None:
+ super().check(schema, seen)
+ assert isinstance(self.tag_member.type, QAPISchemaEnumType)
+ assert not self.tag_member.optional
+ assert not self.tag_member.ifcond.is_present()
+
+
class QAPISchemaMember:
""" Represents object members, enum members and features """
role = 'member'
@@ -1019,7 +1028,7 @@ class QAPISchemaCommand(QAPISchemaDefinition):
"command's 'data' cannot take %s"
% arg_type.describe())
self.arg_type = arg_type
- if self.arg_type.variants and not self.boxed:
+ if self.arg_type.branches and not self.boxed:
raise QAPISemError(
self.info,
"command's 'data' can take %s only with 'boxed': true"
@@ -1087,7 +1096,7 @@ class QAPISchemaEvent(QAPISchemaDefinition):
"event's 'data' cannot take %s"
% typ.describe())
self.arg_type = typ
- if self.arg_type.variants and not self.boxed:
+ if self.arg_type.branches and not self.boxed:
raise QAPISemError(
self.info,
"event's 'data' can take %s only with 'boxed': true"
@@ -1388,8 +1397,8 @@ class QAPISchema:
self._def_definition(
QAPISchemaObjectType(name, info, expr.doc, ifcond, features,
base, members,
- QAPISchemaVariants(
- tag_name, info, None, variants)))
+ QAPISchemaBranches(
+ info, variants, tag_name)))
def _def_alternate_type(self, expr: QAPIExpression) -> None:
name = expr['alternate']
@@ -1407,7 +1416,7 @@ class QAPISchema:
self._def_definition(
QAPISchemaAlternateType(
name, info, expr.doc, ifcond, features,
- QAPISchemaVariants(None, info, tag_member, variants)))
+ QAPISchemaAlternatives(info, variants, tag_member)))
def _def_command(self, expr: QAPIExpression) -> None:
name = expr['command']
diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py
index c39d054..0dd0b00 100644
--- a/scripts/qapi/types.py
+++ b/scripts/qapi/types.py
@@ -23,6 +23,8 @@ from .gen import (
)
from .schema import (
QAPISchema,
+ QAPISchemaAlternatives,
+ QAPISchemaBranches,
QAPISchemaEnumMember,
QAPISchemaFeature,
QAPISchemaIfCond,
@@ -169,7 +171,7 @@ def gen_object(name: str, ifcond: QAPISchemaIfCond,
if not isinstance(obj, QAPISchemaObjectType):
continue
ret += gen_object(obj.name, obj.ifcond, obj.base,
- obj.local_members, obj.variants)
+ obj.local_members, obj.branches)
ret += mcgen('''
@@ -348,13 +350,13 @@ class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor):
features: List[QAPISchemaFeature],
base: Optional[QAPISchemaObjectType],
members: List[QAPISchemaObjectTypeMember],
- variants: Optional[QAPISchemaVariants]) -> None:
+ branches: Optional[QAPISchemaBranches]) -> None:
# Nothing to do for the special empty builtin
if name == 'q_empty':
return
with ifcontext(ifcond, self._genh):
self._genh.preamble_add(gen_fwd_object_or_array(name))
- self._genh.add(gen_object(name, ifcond, base, members, variants))
+ self._genh.add(gen_object(name, ifcond, base, members, branches))
with ifcontext(ifcond, self._genh, self._genc):
if base and not base.is_implicit():
self._genh.add(gen_upcast(name, base))
@@ -369,11 +371,11 @@ class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor):
info: Optional[QAPISourceInfo],
ifcond: QAPISchemaIfCond,
features: List[QAPISchemaFeature],
- variants: QAPISchemaVariants) -> None:
+ alternatives: QAPISchemaAlternatives) -> None:
with ifcontext(ifcond, self._genh):
self._genh.preamble_add(gen_fwd_object_or_array(name))
self._genh.add(gen_object(name, ifcond, None,
- [variants.tag_member], variants))
+ [alternatives.tag_member], alternatives))
with ifcontext(ifcond, self._genh, self._genc):
self._gen_type_cleanup(name)
diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py
index a21b7b1..e766aca 100644
--- a/scripts/qapi/visit.py
+++ b/scripts/qapi/visit.py
@@ -28,6 +28,8 @@ from .gen import (
)
from .schema import (
QAPISchema,
+ QAPISchemaAlternatives,
+ QAPISchemaBranches,
QAPISchemaEnumMember,
QAPISchemaEnumType,
QAPISchemaFeature,
@@ -35,7 +37,6 @@ from .schema import (
QAPISchemaObjectType,
QAPISchemaObjectTypeMember,
QAPISchemaType,
- QAPISchemaVariants,
)
from .source import QAPISourceInfo
@@ -63,7 +64,7 @@ bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp);
def gen_visit_object_members(name: str,
base: Optional[QAPISchemaObjectType],
members: List[QAPISchemaObjectTypeMember],
- variants: Optional[QAPISchemaVariants]) -> str:
+ branches: Optional[QAPISchemaBranches]) -> str:
ret = mcgen('''
bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
@@ -131,8 +132,8 @@ bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
''')
ret += memb.ifcond.gen_endif()
- if variants:
- tag_member = variants.tag_member
+ if branches:
+ tag_member = branches.tag_member
assert isinstance(tag_member.type, QAPISchemaEnumType)
ret += mcgen('''
@@ -140,7 +141,7 @@ bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
''',
c_name=c_name(tag_member.name))
- for var in variants.variants:
+ for var in branches.variants:
case_str = c_enum_const(tag_member.type.name, var.name,
tag_member.type.prefix)
ret += var.ifcond.gen_if()
@@ -222,7 +223,8 @@ bool visit_type_%(c_name)s(Visitor *v, const char *name,
c_name=c_name(name))
-def gen_visit_alternate(name: str, variants: QAPISchemaVariants) -> str:
+def gen_visit_alternate(name: str,
+ alternatives: QAPISchemaAlternatives) -> str:
ret = mcgen('''
bool visit_type_%(c_name)s(Visitor *v, const char *name,
@@ -244,7 +246,7 @@ bool visit_type_%(c_name)s(Visitor *v, const char *name,
''',
c_name=c_name(name))
- for var in variants.variants:
+ for var in alternatives.variants:
ret += var.ifcond.gen_if()
ret += mcgen('''
case %(case)s:
@@ -393,14 +395,14 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
features: List[QAPISchemaFeature],
base: Optional[QAPISchemaObjectType],
members: List[QAPISchemaObjectTypeMember],
- variants: Optional[QAPISchemaVariants]) -> None:
+ branches: Optional[QAPISchemaBranches]) -> None:
# Nothing to do for the special empty builtin
if name == 'q_empty':
return
with ifcontext(ifcond, self._genh, self._genc):
self._genh.add(gen_visit_members_decl(name))
self._genc.add(gen_visit_object_members(name, base,
- members, variants))
+ members, branches))
# TODO Worth changing the visitor signature, so we could
# directly use rather than repeat type.is_implicit()?
if not name.startswith('q_'):
@@ -413,10 +415,10 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
info: Optional[QAPISourceInfo],
ifcond: QAPISchemaIfCond,
features: List[QAPISchemaFeature],
- variants: QAPISchemaVariants) -> None:
+ alternatives: QAPISchemaAlternatives) -> None:
with ifcontext(ifcond, self._genh, self._genc):
self._genh.add(gen_visit_decl(name))
- self._genc.add(gen_visit_alternate(name, variants))
+ self._genc.add(gen_visit_alternate(name, alternatives))
def gen_visit(schema: QAPISchema,