|
@@ -588,11 +588,11 @@ def discriminator_find_enum_define(expr):
|
|
if not base_members:
|
|
if not base_members:
|
|
return None
|
|
return None
|
|
|
|
|
|
- discriminator_type = base_members.get(discriminator)
|
|
|
|
- if not discriminator_type:
|
|
|
|
|
|
+ discriminator_value = base_members.get(discriminator)
|
|
|
|
+ if not discriminator_value:
|
|
return None
|
|
return None
|
|
|
|
|
|
- return enum_types.get(discriminator_type)
|
|
|
|
|
|
+ return enum_types.get(discriminator_value['type'])
|
|
|
|
|
|
|
|
|
|
# Names must be letters, numbers, -, and _. They must start with letter,
|
|
# Names must be letters, numbers, -, and _. They must start with letter,
|
|
@@ -704,8 +704,10 @@ def check_type(info, source, value, allow_array=False,
|
|
% (source, key))
|
|
% (source, key))
|
|
# Todo: allow dictionaries to represent default values of
|
|
# Todo: allow dictionaries to represent default values of
|
|
# an optional argument.
|
|
# an optional argument.
|
|
- check_type(info, "Member '%s' of %s" % (key, source), arg,
|
|
|
|
- allow_array=True,
|
|
|
|
|
|
+ check_known_keys(info, "member '%s' of %s" % (key, source),
|
|
|
|
+ arg, ['type'], [])
|
|
|
|
+ check_type(info, "Member '%s' of %s" % (key, source),
|
|
|
|
+ arg['type'], allow_array=True,
|
|
allow_metas=['built-in', 'union', 'alternate', 'struct',
|
|
allow_metas=['built-in', 'union', 'alternate', 'struct',
|
|
'enum'])
|
|
'enum'])
|
|
|
|
|
|
@@ -776,13 +778,13 @@ def check_union(expr, info):
|
|
# member of the base struct.
|
|
# member of the base struct.
|
|
check_name(info, "Discriminator of flat union '%s'" % name,
|
|
check_name(info, "Discriminator of flat union '%s'" % name,
|
|
discriminator)
|
|
discriminator)
|
|
- discriminator_type = base_members.get(discriminator)
|
|
|
|
- if not discriminator_type:
|
|
|
|
|
|
+ discriminator_value = base_members.get(discriminator)
|
|
|
|
+ if not discriminator_value:
|
|
raise QAPISemError(info,
|
|
raise QAPISemError(info,
|
|
"Discriminator '%s' is not a member of base "
|
|
"Discriminator '%s' is not a member of base "
|
|
"struct '%s'"
|
|
"struct '%s'"
|
|
% (discriminator, base))
|
|
% (discriminator, base))
|
|
- enum_define = enum_types.get(discriminator_type)
|
|
|
|
|
|
+ enum_define = enum_types.get(discriminator_value['type'])
|
|
allow_metas = ['struct']
|
|
allow_metas = ['struct']
|
|
# Do not allow string discriminator
|
|
# Do not allow string discriminator
|
|
if not enum_define:
|
|
if not enum_define:
|
|
@@ -796,9 +798,12 @@ def check_union(expr, info):
|
|
for (key, value) in members.items():
|
|
for (key, value) in members.items():
|
|
check_name(info, "Member of union '%s'" % name, key)
|
|
check_name(info, "Member of union '%s'" % name, key)
|
|
|
|
|
|
|
|
+ check_known_keys(info, "member '%s' of union '%s'" % (key, name),
|
|
|
|
+ value, ['type'], [])
|
|
# Each value must name a known type
|
|
# Each value must name a known type
|
|
check_type(info, "Member '%s' of union '%s'" % (key, name),
|
|
check_type(info, "Member '%s' of union '%s'" % (key, name),
|
|
- value, allow_array=not base, allow_metas=allow_metas)
|
|
|
|
|
|
+ value['type'],
|
|
|
|
+ allow_array=not base, allow_metas=allow_metas)
|
|
|
|
|
|
# If the discriminator names an enum type, then all members
|
|
# If the discriminator names an enum type, then all members
|
|
# of 'data' must also be members of the enum type.
|
|
# of 'data' must also be members of the enum type.
|
|
@@ -822,18 +827,21 @@ def check_alternate(expr, info):
|
|
"in 'data'" % name)
|
|
"in 'data'" % name)
|
|
for (key, value) in members.items():
|
|
for (key, value) in members.items():
|
|
check_name(info, "Member of alternate '%s'" % name, key)
|
|
check_name(info, "Member of alternate '%s'" % name, key)
|
|
|
|
+ check_known_keys(info,
|
|
|
|
+ "member '%s' of alternate '%s'" % (key, name),
|
|
|
|
+ value, ['type'], [])
|
|
|
|
+ typ = value['type']
|
|
|
|
|
|
# Ensure alternates have no type conflicts.
|
|
# Ensure alternates have no type conflicts.
|
|
- check_type(info, "Member '%s' of alternate '%s'" % (key, name),
|
|
|
|
- value,
|
|
|
|
|
|
+ check_type(info, "Member '%s' of alternate '%s'" % (key, name), typ,
|
|
allow_metas=['built-in', 'union', 'struct', 'enum'])
|
|
allow_metas=['built-in', 'union', 'struct', 'enum'])
|
|
- qtype = find_alternate_member_qtype(value)
|
|
|
|
|
|
+ qtype = find_alternate_member_qtype(typ)
|
|
if not qtype:
|
|
if not qtype:
|
|
raise QAPISemError(info, "Alternate '%s' member '%s' cannot use "
|
|
raise QAPISemError(info, "Alternate '%s' member '%s' cannot use "
|
|
- "type '%s'" % (name, key, value))
|
|
|
|
|
|
+ "type '%s'" % (name, key, typ))
|
|
conflicting = set([qtype])
|
|
conflicting = set([qtype])
|
|
if qtype == 'QTYPE_QSTRING':
|
|
if qtype == 'QTYPE_QSTRING':
|
|
- enum_expr = enum_types.get(value)
|
|
|
|
|
|
+ enum_expr = enum_types.get(typ)
|
|
if enum_expr:
|
|
if enum_expr:
|
|
for v in enum_get_names(enum_expr):
|
|
for v in enum_get_names(enum_expr):
|
|
if v in ['on', 'off']:
|
|
if v in ['on', 'off']:
|
|
@@ -851,12 +859,6 @@ def check_alternate(expr, info):
|
|
types_seen[qt] = key
|
|
types_seen[qt] = key
|
|
|
|
|
|
|
|
|
|
-def normalize_enum(expr):
|
|
|
|
- if isinstance(expr['data'], list):
|
|
|
|
- expr['data'] = [m if isinstance(m, dict) else {'name': m}
|
|
|
|
- for m in expr['data']]
|
|
|
|
-
|
|
|
|
-
|
|
|
|
def check_enum(expr, info):
|
|
def check_enum(expr, info):
|
|
name = expr['enum']
|
|
name = expr['enum']
|
|
members = expr['data']
|
|
members = expr['data']
|
|
@@ -928,6 +930,20 @@ def check_keys(expr_elem, meta, required, optional=[]):
|
|
check_if(expr, info)
|
|
check_if(expr, info)
|
|
|
|
|
|
|
|
|
|
|
|
+def normalize_enum(expr):
|
|
|
|
+ if isinstance(expr['data'], list):
|
|
|
|
+ expr['data'] = [m if isinstance(m, dict) else {'name': m}
|
|
|
|
+ for m in expr['data']]
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+def normalize_members(members):
|
|
|
|
+ if isinstance(members, OrderedDict):
|
|
|
|
+ for key, arg in members.items():
|
|
|
|
+ if isinstance(arg, dict):
|
|
|
|
+ continue
|
|
|
|
+ members[key] = {'type': arg}
|
|
|
|
+
|
|
|
|
+
|
|
def check_exprs(exprs):
|
|
def check_exprs(exprs):
|
|
global all_names
|
|
global all_names
|
|
|
|
|
|
@@ -957,22 +973,28 @@ def check_exprs(exprs):
|
|
meta = 'union'
|
|
meta = 'union'
|
|
check_keys(expr_elem, 'union', ['data'],
|
|
check_keys(expr_elem, 'union', ['data'],
|
|
['base', 'discriminator', 'if'])
|
|
['base', 'discriminator', 'if'])
|
|
|
|
+ normalize_members(expr.get('base'))
|
|
|
|
+ normalize_members(expr['data'])
|
|
union_types[expr[meta]] = expr
|
|
union_types[expr[meta]] = expr
|
|
elif 'alternate' in expr:
|
|
elif 'alternate' in expr:
|
|
meta = 'alternate'
|
|
meta = 'alternate'
|
|
check_keys(expr_elem, 'alternate', ['data'], ['if'])
|
|
check_keys(expr_elem, 'alternate', ['data'], ['if'])
|
|
|
|
+ normalize_members(expr['data'])
|
|
elif 'struct' in expr:
|
|
elif 'struct' in expr:
|
|
meta = 'struct'
|
|
meta = 'struct'
|
|
check_keys(expr_elem, 'struct', ['data'], ['base', 'if'])
|
|
check_keys(expr_elem, 'struct', ['data'], ['base', 'if'])
|
|
|
|
+ normalize_members(expr['data'])
|
|
struct_types[expr[meta]] = expr
|
|
struct_types[expr[meta]] = expr
|
|
elif 'command' in expr:
|
|
elif 'command' in expr:
|
|
meta = 'command'
|
|
meta = 'command'
|
|
check_keys(expr_elem, 'command', [],
|
|
check_keys(expr_elem, 'command', [],
|
|
['data', 'returns', 'gen', 'success-response',
|
|
['data', 'returns', 'gen', 'success-response',
|
|
'boxed', 'allow-oob', 'allow-preconfig', 'if'])
|
|
'boxed', 'allow-oob', 'allow-preconfig', 'if'])
|
|
|
|
+ normalize_members(expr.get('data'))
|
|
elif 'event' in expr:
|
|
elif 'event' in expr:
|
|
meta = 'event'
|
|
meta = 'event'
|
|
check_keys(expr_elem, 'event', [], ['data', 'boxed', 'if'])
|
|
check_keys(expr_elem, 'event', [], ['data', 'boxed', 'if'])
|
|
|
|
+ normalize_members(expr.get('data'))
|
|
else:
|
|
else:
|
|
raise QAPISemError(expr_elem['info'],
|
|
raise QAPISemError(expr_elem['info'],
|
|
"Expression is missing metatype")
|
|
"Expression is missing metatype")
|
|
@@ -1716,7 +1738,7 @@ def _make_member(self, name, typ, info):
|
|
return QAPISchemaObjectTypeMember(name, typ, optional)
|
|
return QAPISchemaObjectTypeMember(name, typ, optional)
|
|
|
|
|
|
def _make_members(self, data, info):
|
|
def _make_members(self, data, info):
|
|
- return [self._make_member(key, value, info)
|
|
|
|
|
|
+ return [self._make_member(key, value['type'], info)
|
|
for (key, value) in data.items()]
|
|
for (key, value) in data.items()]
|
|
|
|
|
|
def _def_struct_type(self, expr, info, doc):
|
|
def _def_struct_type(self, expr, info, doc):
|
|
@@ -1752,11 +1774,11 @@ def _def_union_type(self, expr, info, doc):
|
|
name, info, doc, ifcond,
|
|
name, info, doc, ifcond,
|
|
'base', self._make_members(base, info))
|
|
'base', self._make_members(base, info))
|
|
if tag_name:
|
|
if tag_name:
|
|
- variants = [self._make_variant(key, value)
|
|
|
|
|
|
+ variants = [self._make_variant(key, value['type'])
|
|
for (key, value) in data.items()]
|
|
for (key, value) in data.items()]
|
|
members = []
|
|
members = []
|
|
else:
|
|
else:
|
|
- variants = [self._make_simple_variant(key, value, info)
|
|
|
|
|
|
+ variants = [self._make_simple_variant(key, value['type'], info)
|
|
for (key, value) in data.items()]
|
|
for (key, value) in data.items()]
|
|
enum = [{'name': v.name} for v in variants]
|
|
enum = [{'name': v.name} for v in variants]
|
|
typ = self._make_implicit_enum_type(name, info, ifcond, enum)
|
|
typ = self._make_implicit_enum_type(name, info, ifcond, enum)
|
|
@@ -1772,7 +1794,7 @@ def _def_alternate_type(self, expr, info, doc):
|
|
name = expr['alternate']
|
|
name = expr['alternate']
|
|
data = expr['data']
|
|
data = expr['data']
|
|
ifcond = expr.get('if')
|
|
ifcond = expr.get('if')
|
|
- variants = [self._make_variant(key, value)
|
|
|
|
|
|
+ variants = [self._make_variant(key, value['type'])
|
|
for (key, value) in data.items()]
|
|
for (key, value) in data.items()]
|
|
tag_member = QAPISchemaObjectTypeMember('type', 'QType', False)
|
|
tag_member = QAPISchemaObjectTypeMember('type', 'QType', False)
|
|
self._def_entity(
|
|
self._def_entity(
|