|
@@ -29,6 +29,7 @@
|
|
List,
|
|
List,
|
|
Optional,
|
|
Optional,
|
|
Union,
|
|
Union,
|
|
|
|
+ ValuesView,
|
|
cast,
|
|
cast,
|
|
)
|
|
)
|
|
|
|
|
|
@@ -933,8 +934,11 @@ def connect_doc(self, doc: Optional[QAPIDoc]) -> None:
|
|
class QAPISchemaFeature(QAPISchemaMember):
|
|
class QAPISchemaFeature(QAPISchemaMember):
|
|
role = 'feature'
|
|
role = 'feature'
|
|
|
|
|
|
|
|
+ # Features which are standardized across all schemas
|
|
|
|
+ SPECIAL_NAMES = ['deprecated', 'unstable']
|
|
|
|
+
|
|
def is_special(self) -> bool:
|
|
def is_special(self) -> bool:
|
|
- return self.name in ('deprecated', 'unstable')
|
|
|
|
|
|
+ return self.name in QAPISchemaFeature.SPECIAL_NAMES
|
|
|
|
|
|
|
|
|
|
class QAPISchemaObjectTypeMember(QAPISchemaMember):
|
|
class QAPISchemaObjectTypeMember(QAPISchemaMember):
|
|
@@ -1138,6 +1142,16 @@ def __init__(self, fname: str):
|
|
self._entity_list: List[QAPISchemaEntity] = []
|
|
self._entity_list: List[QAPISchemaEntity] = []
|
|
self._entity_dict: Dict[str, QAPISchemaDefinition] = {}
|
|
self._entity_dict: Dict[str, QAPISchemaDefinition] = {}
|
|
self._module_dict: Dict[str, QAPISchemaModule] = OrderedDict()
|
|
self._module_dict: Dict[str, QAPISchemaModule] = OrderedDict()
|
|
|
|
+ # NB, values in the dict will identify the first encountered
|
|
|
|
+ # usage of a named feature only
|
|
|
|
+ self._feature_dict: Dict[str, QAPISchemaFeature] = OrderedDict()
|
|
|
|
+
|
|
|
|
+ # All schemas get the names defined in the QapiSpecialFeature enum.
|
|
|
|
+ # Rely on dict iteration order matching insertion order so that
|
|
|
|
+ # the special names are emitted first when generating code.
|
|
|
|
+ for f in QAPISchemaFeature.SPECIAL_NAMES:
|
|
|
|
+ self._feature_dict[f] = QAPISchemaFeature(f, None)
|
|
|
|
+
|
|
self._schema_dir = os.path.dirname(fname)
|
|
self._schema_dir = os.path.dirname(fname)
|
|
self._make_module(QAPISchemaModule.BUILTIN_MODULE_NAME)
|
|
self._make_module(QAPISchemaModule.BUILTIN_MODULE_NAME)
|
|
self._make_module(fname)
|
|
self._make_module(fname)
|
|
@@ -1147,6 +1161,9 @@ def __init__(self, fname: str):
|
|
self._def_exprs(exprs)
|
|
self._def_exprs(exprs)
|
|
self.check()
|
|
self.check()
|
|
|
|
|
|
|
|
+ def features(self) -> ValuesView[QAPISchemaFeature]:
|
|
|
|
+ return self._feature_dict.values()
|
|
|
|
+
|
|
def _def_entity(self, ent: QAPISchemaEntity) -> None:
|
|
def _def_entity(self, ent: QAPISchemaEntity) -> None:
|
|
self._entity_list.append(ent)
|
|
self._entity_list.append(ent)
|
|
|
|
|
|
@@ -1258,6 +1275,12 @@ def _make_features(
|
|
) -> List[QAPISchemaFeature]:
|
|
) -> List[QAPISchemaFeature]:
|
|
if features is None:
|
|
if features is None:
|
|
return []
|
|
return []
|
|
|
|
+
|
|
|
|
+ for f in features:
|
|
|
|
+ feat = QAPISchemaFeature(f['name'], info)
|
|
|
|
+ if feat.name not in self._feature_dict:
|
|
|
|
+ self._feature_dict[feat.name] = feat
|
|
|
|
+
|
|
return [QAPISchemaFeature(f['name'], info,
|
|
return [QAPISchemaFeature(f['name'], info,
|
|
QAPISchemaIfCond(f.get('if')))
|
|
QAPISchemaIfCond(f.get('if')))
|
|
for f in features]
|
|
for f in features]
|
|
@@ -1485,6 +1508,12 @@ def check(self) -> None:
|
|
for doc in self.docs:
|
|
for doc in self.docs:
|
|
doc.check()
|
|
doc.check()
|
|
|
|
|
|
|
|
+ features = list(self._feature_dict.values())
|
|
|
|
+ if len(features) > 64:
|
|
|
|
+ raise QAPISemError(
|
|
|
|
+ features[64].info,
|
|
|
|
+ "Maximum of 64 schema features is permitted")
|
|
|
|
+
|
|
def visit(self, visitor: QAPISchemaVisitor) -> None:
|
|
def visit(self, visitor: QAPISchemaVisitor) -> None:
|
|
visitor.visit_begin(self)
|
|
visitor.visit_begin(self)
|
|
for mod in self._module_dict.values():
|
|
for mod in self._module_dict.values():
|