qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: qemu-devel@nongnu.org
Cc: mdroth@linux.vnet.ibm.com
Subject: [Qemu-devel] [PATCH v7 26/26] qapi-introspect: Hide type names
Date: Mon, 14 Sep 2015 19:57:57 +0200	[thread overview]
Message-ID: <1442253477-15422-27-git-send-email-armbru@redhat.com> (raw)
In-Reply-To: <1442253477-15422-1-git-send-email-armbru@redhat.com>

To eliminate the temptation for clients to look up types by name
(which are not ABI), replace all type names by meaningless strings.

Reduces output of query-schema by 13 out of 85KiB.

As a debugging aid, provide option -u to suppress the hiding.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
 docs/qapi-code-gen.txt     | 36 +++++++++++++++++-------------------
 qapi/introspect.json       | 12 ++++--------
 scripts/qapi-introspect.py | 41 +++++++++++++++++++++++++++++++++++------
 3 files changed, 56 insertions(+), 33 deletions(-)

diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index 458b217..01e292b 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -522,13 +522,16 @@ additional variant members depending on the value of meta-type.
 Each SchemaInfo object describes a wire ABI entity of a certain
 meta-type: a command, event or one of several kinds of type.
 
-SchemaInfo for entities defined in the QAPI schema have the same name
-as in the schema.  This is the case for all commands and events, and
-most types.
+SchemaInfo for commands and events have the same name as in the QAPI
+schema.
 
 Command and event names are part of the wire ABI, but type names are
-not.  Therefore, looking up a type by its name in the QAPI schema is
-wrong.  Look up the command or event, then follow references by name.
+not.  Therefore, the SchemaInfo for types have auto-generated
+meaningless names.  For readability, the examples in this section use
+meaningful type names instead.
+
+To examine a type, start with a command or event using it, then follow
+references by name.
 
 QAPI schema definitions not reachable that way are omitted.
 
@@ -559,8 +562,7 @@ object type without members.  The event may not have a data member on
 the wire then.
 
 Each command or event defined with dictionary-valued 'data' in the
-QAPI schema implicitly defines an object type called ":obj-NAME-arg",
-where NAME is the command or event's name.
+QAPI schema implicitly defines an object type.
 
 Example: the SchemaInfo for EVENT_C from section Events
 
@@ -615,12 +617,9 @@ Note that base types are "flattened": its members are included in the
 
 A simple union implicitly defines an enumeration type for its implicit
 discriminator (called "type" on the wire, see section Union types).
-Such a type's name is made by appending "Kind" to the simple union's
-name.
 
 A simple union implicitly defines an object type for each of its
-variants.  The type's name is ":obj-NAME-wrapper", where NAME is the
-name of the name of the variant's type.
+variants.
 
 Example: the SchemaInfo for simple union BlockdevOptions from section
 Union types
@@ -651,8 +650,7 @@ Example: the SchemaInfo for BlockRef from section Alternate types
 
 The SchemaInfo for an array type has meta-type "array", and variant
 member "element-type", which names the array's element type.  Array
-types are implicitly defined.  An array type's name is made by
-appending "List" to its element type's name.
+types are implicitly defined.
 
 Example: the SchemaInfo for ['str']
 
@@ -1059,13 +1057,13 @@ Example:
 [Uninteresting stuff omitted...]
 
     const char example_qmp_schema_json[] = "["
-        "{\"arg-type\": \":empty\", \"meta-type\": \"event\", \"name\": \"MY_EVENT\"}, "
+        "{\"arg-type\": \"0\", \"meta-type\": \"event\", \"name\": \"MY_EVENT\"}, "
+        "{\"arg-type\": \"1\", \"meta-type\": \"command\", \"name\": \"my-command\", \"ret-type\": \"2\"}, "
+        "{\"members\": [], \"meta-type\": \"object\", \"name\": \"0\"}, "
+        "{\"members\": [{\"name\": \"arg1\", \"type\": \"2\"}], \"meta-type\": \"object\", \"name\": \"1\"}, "
+        "{\"members\": [{\"name\": \"integer\", \"type\": \"int\"}, {\"name\": \"string\", \"type\": \"str\"}], \"meta-type\": \"object\", \"name\": \"2\"}, "
         "{\"json-type\": \"int\", \"meta-type\": \"builtin\", \"name\": \"int\"}, "
-        "{\"json-type\": \"string\", \"meta-type\": \"builtin\", \"name\": \"str\"}, "
-        "{\"members\": [], \"meta-type\": \"object\", \"name\": \":empty\"}, "
-        "{\"members\": [{\"name\": \"arg1\", \"type\": \"UserDefOne\"}], \"meta-type\": \"object\", \"name\": \":obj-my-command-arg\"}, "
-        "{\"members\": [{\"name\": \"integer\", \"type\": \"int\"}, {\"name\": \"string\", \"type\": \"str\"}], \"meta-type\": \"object\", \"name\": \"UserDefOne\"}, "
-        "{\"arg-type\": \":obj-my-command-arg\", \"meta-type\": \"command\", \"name\": \"my-command\", \"ret-type\": \"UserDefOne\"}]";
+        "{\"json-type\": \"string\", \"meta-type\": \"builtin\", \"name\": \"str\"}]";
     $ cat qapi-generated/example-qmp-introspect.h
 [Uninteresting stuff omitted...]
 
diff --git a/qapi/introspect.json b/qapi/introspect.json
index 9c8ad53..cc50dc6 100644
--- a/qapi/introspect.json
+++ b/qapi/introspect.json
@@ -75,17 +75,13 @@
 # @SchemaInfo
 #
 # @name: the entity's name, inherited from @base.
-#         Entities defined in the QAPI schema have the name defined in
-#         the schema.  Implicitly defined entities have generated
-#         names.  See docs/qapi-code-gen.txt section "Client JSON
-#         Protocol introspection" for details.
+#        Commands and events have the name defined in the QAPI schema.
+#        Unlike command and event names, type names are not part of
+#        the wire ABI.  Consequently, type names are meaningless
+#        strings here.
 #
 # All references to other SchemaInfo are by name.
 #
-# Command and event names are part of the wire ABI, but type names are
-# not.  Therefore, looking up a type by "well-known" name is wrong.
-# Look up the command or event, then follow the references.
-#
 # @meta-type: the entity's meta type, inherited from @base.
 #
 # Additional members depend on the value of @meta-type.
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index 1bc26f0..ce98321 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -40,32 +40,37 @@ def to_c_string(string):
 
 
 class QAPISchemaGenIntrospectVisitor(QAPISchemaVisitor):
-    def __init__(self):
+    def __init__(self, unmask):
+        self._unmask = unmask
         self.defn = None
         self.decl = None
         self._schema = None
         self._jsons = None
         self._used_types = None
+        self._name_map = None
 
     def visit_begin(self, schema):
         self._schema = schema
         self._jsons = []
         self._used_types = []
+        self._name_map = {}
         return QAPISchemaType   # don't visit types for now
 
     def visit_end(self):
         # visit the types that are actually used
+        jsons = self._jsons
+        self._jsons = []
         for typ in self._used_types:
             typ.visit(self)
-        self._jsons.sort()
         # generate C
         # TODO can generate awfully long lines
+        jsons.extend(self._jsons)
         name = prefix + 'qmp_schema_json'
         self.decl = mcgen('''
 extern const char %(c_name)s[];
 ''',
                           c_name=c_name(name))
-        lines = to_json(self._jsons).split('\n')
+        lines = to_json(jsons).split('\n')
         c_string = '\n    '.join([to_c_string(line) for line in lines])
         self.defn = mcgen('''
 const char %(c_name)s[] = %(c_string)s;
@@ -75,6 +80,14 @@ const char %(c_name)s[] = %(c_string)s;
         self._schema = None
         self._jsons = None
         self._used_types = None
+        self._name_map = None
+
+    def _name(self, name):
+        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]
 
     def _use_type(self, typ):
         # Map the various integer types to plain int
@@ -86,9 +99,16 @@ const char %(c_name)s[] = %(c_string)s;
         # Add type to work queue if new
         if typ not in self._used_types:
             self._used_types.append(typ)
-        return typ.name
+        # Clients should examine commands and events, not types.  Hide
+        # type names to reduce the temptation.  Also saves a few
+        # characters.
+        if isinstance(typ, QAPISchemaBuiltinType):
+            return typ.name
+        return self._name(typ.name)
 
     def _gen_json(self, name, mtype, obj):
+        if mtype != 'command' and mtype != 'event' and mtype != 'builtin':
+            name = self._name(name)
         obj['name'] = name
         obj['meta-type'] = mtype
         self._jsons.append(obj)
@@ -140,7 +160,16 @@ const char %(c_name)s[] = %(c_string)s;
         arg_type = arg_type or self._schema.the_empty_object_type
         self._gen_json(name, 'event', {'arg-type': self._use_type(arg_type)})
 
-(input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line()
+# Debugging aid: unmask QAPI schema's type names
+# We normally mask them, because they're not QMP wire ABI
+opt_unmask = False
+
+(input_file, output_dir, do_c, do_h, prefix, opts) = \
+    parse_command_line("u", ["unmask-non-abi-names"])
+
+for o, a in opts:
+    if o in ("-u", "--unmask-non-abi-names"):
+        opt_unmask = True
 
 c_comment = '''
 /*
@@ -176,7 +205,7 @@ fdef.write(mcgen('''
                  prefix=prefix))
 
 schema = QAPISchema(input_file)
-gen = QAPISchemaGenIntrospectVisitor()
+gen = QAPISchemaGenIntrospectVisitor(opt_unmask)
 schema.visit(gen)
 fdef.write(gen.defn)
 fdecl.write(gen.decl)
-- 
2.4.3

  parent reply	other threads:[~2015-09-14 17:58 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-14 17:57 [Qemu-devel] [PATCH v7 00/26] qapi: QMP introspection Markus Armbruster
2015-09-14 17:57 ` [Qemu-devel] [PATCH v7 01/26] qapi: Rename class QAPISchema to QAPISchemaParser Markus Armbruster
2015-09-14 17:57 ` [Qemu-devel] [PATCH v7 02/26] qapi: New QAPISchema intermediate reperesentation Markus Armbruster
2015-09-14 17:57 ` [Qemu-devel] [PATCH v7 03/26] qapi: QAPISchema code generation helper methods Markus Armbruster
2015-09-14 17:57 ` [Qemu-devel] [PATCH v7 04/26] qapi: New QAPISchemaVisitor Markus Armbruster
2015-09-14 17:57 ` [Qemu-devel] [PATCH v7 05/26] tests/qapi-schema: Convert test harness to QAPISchemaVisitor Markus Armbruster
2015-09-14 17:57 ` [Qemu-devel] [PATCH v7 06/26] qapi-types: Convert to QAPISchemaVisitor, fixing flat unions Markus Armbruster
2015-09-14 17:57 ` [Qemu-devel] [PATCH v7 07/26] qapi-visit: Convert to QAPISchemaVisitor, fixing bugs Markus Armbruster
2015-09-14 17:57 ` [Qemu-devel] [PATCH v7 08/26] qapi-commands: Convert to QAPISchemaVisitor Markus Armbruster
2015-09-14 17:57 ` [Qemu-devel] [PATCH v7 09/26] qapi: De-duplicate enum code generation Markus Armbruster
2015-09-15 10:46   ` Daniel P. Berrange
2015-09-14 17:57 ` [Qemu-devel] [PATCH v7 10/26] qapi-event: Eliminate global variable event_enum_value Markus Armbruster
2015-09-15 10:47   ` Daniel P. Berrange
2015-09-14 17:57 ` [Qemu-devel] [PATCH v7 11/26] qapi-event: Convert to QAPISchemaVisitor, fixing data with base Markus Armbruster
2015-09-14 17:57 ` [Qemu-devel] [PATCH v7 12/26] qapi: Replace dirty is_c_ptr() by method c_null() Markus Armbruster
2015-09-15 10:48   ` Daniel P. Berrange
2015-09-14 17:57 ` [Qemu-devel] [PATCH v7 13/26] qapi: Clean up after recent conversions to QAPISchemaVisitor Markus Armbruster
2015-09-15 10:52   ` Daniel P. Berrange
2015-09-15 14:03     ` Eric Blake
2015-09-14 17:57 ` [Qemu-devel] [PATCH v7 14/26] qapi-visit: Rearrange code a bit Markus Armbruster
2015-09-15 10:53   ` Daniel P. Berrange
2015-09-14 17:57 ` [Qemu-devel] [PATCH v7 15/26] qapi-commands: Rearrange code Markus Armbruster
2015-09-15 10:54   ` Daniel P. Berrange
2015-09-14 17:57 ` [Qemu-devel] [PATCH v7 16/26] qapi: Rename qmp_marshal_input_FOO() to qmp_marshal_FOO() Markus Armbruster
2015-09-15 10:55   ` Daniel P. Berrange
2015-09-14 17:57 ` [Qemu-devel] [PATCH v7 17/26] qapi: De-duplicate parameter list generation Markus Armbruster
2015-09-15 10:57   ` Daniel P. Berrange
2015-09-14 17:57 ` [Qemu-devel] [PATCH v7 18/26] qapi-commands: De-duplicate output marshaling functions Markus Armbruster
2015-09-15 11:10   ` Daniel P. Berrange
2015-09-14 17:57 ` [Qemu-devel] [PATCH v7 19/26] qapi: Improve built-in type documentation Markus Armbruster
2015-09-15 11:15   ` Daniel P. Berrange
2015-09-14 17:57 ` [Qemu-devel] [PATCH v7 20/26] qapi: Make output visitor return qnull() instead of NULL Markus Armbruster
2015-09-14 19:07   ` Eric Blake
2015-09-15 11:37   ` Daniel P. Berrange
2015-09-15 13:20     ` Markus Armbruster
2015-09-15 14:08       ` Eric Blake
2015-09-14 17:57 ` [Qemu-devel] [PATCH v7 21/26] qapi: Introduce a first class 'any' type Markus Armbruster
2015-09-15 11:39   ` Daniel P. Berrange
2015-09-14 17:57 ` [Qemu-devel] [PATCH v7 22/26] qom: Don't use 'gen': false for qom-get, qom-set, object-add Markus Armbruster
2015-09-15 11:42   ` Daniel P. Berrange
2015-09-14 17:57 ` [Qemu-devel] [PATCH v7 23/26] qapi-schema: Fix up misleading specification of netdev_add Markus Armbruster
2015-09-15 11:43   ` Daniel P. Berrange
2015-09-14 17:57 ` [Qemu-devel] [PATCH v7 24/26] qapi: Pseudo-type '**' is now unused, drop it Markus Armbruster
2015-09-15 11:44   ` Daniel P. Berrange
2015-09-14 17:57 ` [Qemu-devel] [PATCH v7 25/26] qapi: New QMP command query-qmp-schema for QMP introspection Markus Armbruster
2015-09-14 17:57 ` Markus Armbruster [this message]
2015-09-15 18:14 ` [Qemu-devel] [PATCH v7 00/26] qapi: " Markus Armbruster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1442253477-15422-27-git-send-email-armbru@redhat.com \
    --to=armbru@redhat.com \
    --cc=mdroth@linux.vnet.ibm.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).