<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Oct 25, 2021 at 1:26 AM Markus Armbruster <<a href="mailto:armbru@redhat.com">armbru@redhat.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">By convention, names starting with "x-" are experimental.  The parts<br>
of external interfaces so named may be withdrawn or changed<br>
incompatibly in future releases.<br>
<br>
Drawback: promoting something from experimental to stable involves a<br>
name change.  Client code needs to be updated.<br>
<br>
Moreover, the convention is not universally observed:<br>
<br>
* QOM type "input-barrier" has properties "x-origin", "y-origin".<br>
  Looks accidental, but it's ABI since 4.2.<br>
<br>
* QOM types "memory-backend-file", "memory-backend-memfd",<br>
  "memory-backend-ram", and "memory-backend-epc" have a property<br>
  "x-use-canonical-path-for-ramblock-id" that is documented to be<br>
  stable despite its name.<br>
<br>
We could document these exceptions, but documentation helps only<br>
humans.  We want to recognize "unstable" in code, like "deprecated".<br>
<br>
Replace the convention by a new special feature flag "unstable".  It<br>
will be recognized by the QAPI generator, like the existing feature<br>
flag "deprecated", and unlike regular feature flags.<br>
<br>
This commit updates documentation and prepares tests.  The next commit<br>
updates the QAPI schema.  The remaining patches update the QAPI<br>
generator and wire up -compat policy checking.<br>
<br>
Signed-off-by: Markus Armbruster <<a href="mailto:armbru@redhat.com" target="_blank">armbru@redhat.com</a>><br>
---<br>
 docs/devel/qapi-code-gen.rst            | 9 ++++++---<br>
 tests/qapi-schema/qapi-schema-test.json | 7 +++++--<br>
 tests/qapi-schema/qapi-schema-test.out  | 5 +++++<br>
 3 files changed, 16 insertions(+), 5 deletions(-)<br>
<br>
diff --git a/docs/devel/qapi-code-gen.rst b/docs/devel/qapi-code-gen.rst<br>
index 4071c9074a..38f2d7aad3 100644<br>
--- a/docs/devel/qapi-code-gen.rst<br>
+++ b/docs/devel/qapi-code-gen.rst<br>
@@ -713,6 +713,10 @@ member as deprecated.  It is not supported elsewhere so far.<br>
 Interfaces so marked may be withdrawn in future releases in accordance<br>
 with QEMU's deprecation policy.<br>
<br>
+Feature "unstable" marks a command, event, enum value, or struct<br>
+member as unstable.  It is not supported elsewhere so far.  Interfaces<br>
+so marked may be withdrawn or changed incompatibly in future releases.<br>
+<br>
<br>
 Naming rules and reserved names<br>
 -------------------------------<br>
@@ -746,9 +750,8 @@ Member name ``u`` and names starting with ``has-`` or ``has_`` are reserved<br>
 for the generator, which uses them for unions and for tracking<br>
 optional members.<br>
<br>
-Any name (command, event, type, member, or enum value) beginning with<br>
-``x-`` is marked experimental, and may be withdrawn or changed<br>
-incompatibly in a future release.<br>
+Names beginning with ``x-`` used to signify "experimental".  This<br>
+convention has been replaced by special feature "unstable".<br>
<br>
 Pragmas ``command-name-exceptions`` and ``member-name-exceptions`` let<br>
 you violate naming rules.  Use for new code is strongly discouraged. See<br>
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json<br>
index b677ab861d..43b8697002 100644<br>
--- a/tests/qapi-schema/qapi-schema-test.json<br>
+++ b/tests/qapi-schema/qapi-schema-test.json<br>
@@ -273,7 +273,7 @@<br>
   'data': { 'foo': { 'type': 'int', 'features': [ 'deprecated' ] } },<br>
   'features': [ 'feature1' ] }<br>
 { 'struct': 'FeatureStruct2',<br>
-  'data': { 'foo': 'int' },<br>
+  'data': { 'foo': { 'type': 'int', 'features': [ 'unstable' ] } },<br>
   'features': [ { 'name': 'feature1' } ] }<br>
 { 'struct': 'FeatureStruct3',<br>
   'data': { 'foo': 'int' },<br>
@@ -331,7 +331,7 @@<br>
 { 'command': 'test-command-features1',<br>
   'features': [ 'deprecated' ] }<br>
 { 'command': 'test-command-features3',<br>
-  'features': [ 'feature1', 'feature2' ] }<br>
+  'features': [ 'unstable', 'feature1', 'feature2' ] }<br>
<br>
 { 'command': 'test-command-cond-features1',<br>
   'features': [ { 'name': 'feature1', 'if': 'TEST_IF_FEATURE_1'} ] }<br>
@@ -348,3 +348,6 @@<br>
<br>
 { 'event': 'TEST_EVENT_FEATURES1',<br>
   'features': [ 'deprecated' ] }<br>
+<br>
+{ 'event': 'TEST_EVENT_FEATURES2',<br>
+  'features': [ 'unstable' ] }<br>
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out<br>
index 16846dbeb8..1f9585fa9b 100644<br>
--- a/tests/qapi-schema/qapi-schema-test.out<br>
+++ b/tests/qapi-schema/qapi-schema-test.out<br>
@@ -308,6 +308,7 @@ object FeatureStruct1<br>
     feature feature1<br>
 object FeatureStruct2<br>
     member foo: int optional=False<br>
+        feature unstable<br>
     feature feature1<br>
 object FeatureStruct3<br>
     member foo: int optional=False<br>
@@ -373,6 +374,7 @@ command test-command-features1 None -> None<br>
     feature deprecated<br>
 command test-command-features3 None -> None<br>
     gen=True success_response=True boxed=False oob=False preconfig=False<br>
+    feature unstable<br>
     feature feature1<br>
     feature feature2<br>
 command test-command-cond-features1 None -> None<br>
@@ -394,6 +396,9 @@ event TEST_EVENT_FEATURES0 FeatureStruct1<br>
 event TEST_EVENT_FEATURES1 None<br>
     boxed=False<br>
     feature deprecated<br>
+event TEST_EVENT_FEATURES2 None<br>
+    boxed=False<br>
+    feature unstable<br>
 module include/sub-module.json<br>
 include sub-sub-module.json<br>
 object SecondArrayRef<br>
-- <br>
2.31.1<br>
<br></blockquote></div><div class="gmail_quote"><br></div><div class="gmail_quote">Feels odd to combine the doc update *and* test prep, but eh, whatever.</div><div class="gmail_quote"><br></div><div class="gmail_quote">Reviewed-by: John Snow <<a href="mailto:jsnow@redhat.com">jsnow@redhat.com</a>><br></div></div>