From: Markus Armbruster <[email protected]> query-qmp-schema masks type names, because they are not part of the external interface. Marc-André Lureau would like to also use them with qom-list & friends. Trouble is the masked names are buried deep in QAPISchemaGenIntrospectVisitor. Lift them into schema.py: new QAPISchemaDefinition method introspection_name() returns a definition's name for use in introspection.
This changes the masked names, which is fine. Signed-off-by: Markus Armbruster <[email protected]> Reviewed-by: Marc-André Lureau <[email protected]> --- scripts/qapi/introspect.py | 23 ++++------------------- scripts/qapi/schema.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py index 7e28de2279ad..644461560c64 100644 --- a/scripts/qapi/introspect.py +++ b/scripts/qapi/introspect.py @@ -30,7 +30,6 @@ QAPISchemaAlternatives, QAPISchemaArrayType, QAPISchemaBranches, - QAPISchemaBuiltinType, QAPISchemaEntity, QAPISchemaEnumMember, QAPISchemaFeature, @@ -177,7 +176,6 @@ def __init__(self, prefix: str, unmask: bool): self._schema: Optional[QAPISchema] = None self._trees: List[Annotated[SchemaInfo]] = [] self._used_types: List[QAPISchemaType] = [] - self._name_map: Dict[str, str] = {} self._genc.add(mcgen(''' #include "qemu/osdep.h" #include "%(prefix)sqapi-introspect.h" @@ -208,18 +206,14 @@ def visit_end(self) -> None: self._schema = None self._trees = [] self._used_types = [] - self._name_map = {} def visit_needed(self, entity: QAPISchemaEntity) -> bool: # Ignore types on first pass; visit_end() will pick up used types return not isinstance(entity, QAPISchemaType) def _name(self, name: str) -> str: - if self._unmask: - return name - if name not in self._name_map: - self._name_map[name] = '%d' % len(self._name_map) - return self._name_map[name] + assert self._schema + return self._schema.definition_introspection_name(name, self._unmask) def _use_type(self, typ: QAPISchemaType) -> str: assert self._schema is not None @@ -237,13 +231,6 @@ def _use_type(self, typ: QAPISchemaType) -> str: # Add type to work queue if new if typ not in self._used_types: self._used_types.append(typ) - # Clients should examine commands and events, not types. Hide - # type names as integers to reduce the temptation. Also, it - # saves a few characters on the wire. - if isinstance(typ, QAPISchemaBuiltinType): - return typ.name - if isinstance(typ, QAPISchemaArrayType): - return '[' + self._use_type(typ.element_type) + ']' return self._name(typ.name) @staticmethod @@ -271,8 +258,7 @@ def _gen_tree(self, name: str, mtype: str, obj: Dict[str, object], # Output a comment to make it easy to map masked names # back to the source when reading the generated output. comment = f'"{self._name(name)}" = {name}' - name = self._name(name) - obj['name'] = name + obj['name'] = self._name(name) obj['meta-type'] = mtype if features: obj['features'] = self._gen_features(features) @@ -327,8 +313,7 @@ def visit_array_type(self, name: str, info: Optional[QAPISourceInfo], ifcond: QAPISchemaIfCond, element_type: QAPISchemaType) -> None: element = self._use_type(element_type) - self._gen_tree('[' + element + ']', 'array', {'element-type': element}, - ifcond) + self._gen_tree(name, 'array', {'element-type': element}, ifcond) def visit_object_type_flat(self, name: str, info: Optional[QAPISourceInfo], ifcond: QAPISchemaIfCond, diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index 9c9e257a8fd5..11f3accec873 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -136,6 +136,13 @@ def __repr__(self) -> str: def c_name(self) -> str: return c_name(self.name) + def set_ordinal(self, ordinal: int) -> None: + pass + + # pylint: disable=unused-argument + def introspection_name(self, unmask: bool) -> str: + return self.name + def check(self, schema: QAPISchema) -> None: assert not self._checked super().check(schema) @@ -323,6 +330,17 @@ def visit(self, visitor: QAPISchemaVisitor) -> None: class QAPISchemaType(QAPISchemaDefinition, ABC): + def __init__( + self, + name: str, + info: Optional[QAPISourceInfo], + doc: Optional[QAPIDoc], + ifcond: Optional[QAPISchemaIfCond] = None, + features: Optional[List[QAPISchemaFeature]] = None, + ): + super().__init__(name, info, doc, ifcond, features) + self._masked_name: Optional[str] = None + # Return the C type for common use. # For the types we commonly box, this is a pointer type. @abstractmethod @@ -363,6 +381,17 @@ def need_has_if_optional(self) -> bool: # Except for arrays; see QAPISchemaArrayType.need_has_if_optional(). return not self.c_type().endswith(POINTER_SUFFIX) + def set_ordinal(self, ordinal: int) -> None: + assert not self._masked_name + self._masked_name = str(ordinal) + + def introspection_name(self, unmask: bool) -> str: + # Type names are not part of the external interface. Hide + # them in introspection. Also saves a few characters on the + # wire. + assert self._masked_name + return self.name if unmask else self._masked_name + def check(self, schema: QAPISchema) -> None: super().check(schema) for feat in self.features: @@ -402,6 +431,11 @@ def json_type(self) -> str: def doc_type(self) -> str: return self.json_type() + def introspection_name(self, unmask: bool): + if self.json_type() == 'int': + return 'int' + return self.name + def visit(self, visitor: QAPISchemaVisitor) -> None: super().visit(visitor) visitor.visit_builtin_type(self.name, self.info, self.json_type()) @@ -503,6 +537,9 @@ def doc_type(self) -> Optional[str]: return None return 'array of ' + elt_doc_type + def introspection_name(self, unmask: bool): + return '[' + self.element_type.introspection_name(unmask) + ']' + def visit(self, visitor: QAPISchemaVisitor) -> None: super().visit(visitor) visitor.visit_array_type(self.name, self.info, self.ifcond, @@ -1182,6 +1219,7 @@ def _def_definition(self, defn: QAPISchemaDefinition) -> None: "'%s' is already defined\n%s" % (defn.name, where)) raise QAPISemError( defn.info, "%s is already defined" % other_defn.describe()) + defn.set_ordinal(len(self._entity_dict)) self._entity_dict[defn.name] = defn def lookup_defn(self, name: str) -> Optional[QAPISchemaDefinition]: @@ -1208,6 +1246,11 @@ def resolve_type( info, "%s uses unknown type '%s'" % (what, name)) return typ + def definition_introspection_name(self, name: str, unmask: bool) -> str: + defn = self.lookup_defn(name) + assert defn + return defn.introspection_name(unmask) + def _module_name(self, fname: str) -> str: if QAPISchemaModule.is_system_module(fname): return fname -- 2.56.0.116.g6de20f6092dc
