Markus Armbruster <arm...@redhat.com> writes: > Paolo Bonzini <pbonz...@redhat.com> writes: > >> Il dom 2 feb 2020, 10:22 Kevin Wolf <kw...@redhat.com> ha scritto: >> >>> Am 31.01.2020 um 13:27 hat Eric Blake geschrieben: >>> > On 1/28/20 6:54 AM, Kevin Wolf wrote: >>> > >>> > > > >>> > > > The arguments as dotted keys: >>> > > > >>> > > > id=bar,backend.type=file,backend.data.out=/tmp/bar.log >>> > > > >>> > > > Observe there's quite some of nesting. While that's somewhat >>> cumbersome >>> > > > in JSON, it's a lot worse with dotted keys, because there nesting >>> means >>> > > > repeated key prefixes. I could give much worse examples, actually. >>> > > >>> > > This is true, but even without the repeated keys (e.g. in a syntax that >>> > > would use brackets), it would still be unnecessarily verbose and >>> > > probably hard to remember: >>> > > >>> > > id=bar,backend={type=file,data={out=/tmp/bar.log}} >>> >>> [...] I actually think that a syntax like this might make sense for >>> something like qmp-shell. It might even be more convenient on the >>> command line than dotted keys if you get a lot of repetition (despite >>> the required quoting), but it's strictly speaking incompatible because >>> you could use {} in strings today. >>> >> >> If you are willing to feed schema info to the parser, in principle you >> could keep backwards compatibility. There would be limitations such as >> putting the discriminator before the fields, so I am not sure it's a good >> idea. > > Problem: the 'any' type, where the schema doesn't provide the necessary > information. > > Problem: 'gen': false, where we pass the arguments raw, ignoring the > schema. > > If we didn't restrict alternate types so severly, it would also be a > problem. For instance, with > > { 'alternate': 'Alt', > 'data': { 'one': 'number', > 'two': 'str' } } > > we don't know what to do for value "on" branch to take for value 42. > Not a problem because we reject this alternate. See > tests/qapi-schema/alternate-conflict-*json for more examples. > >> Better QOM introspection would be a requirement, too. > > I guess this is what you believe is needed to solve these problems.
Here's how we currently solve them. We have four pipelines from text to QAPI objects: 1. JSON: JSON QObject wrapped QAPI text --> parser --> QObject --> in plain qobject --> visit --> object input visitor 2. keyval: keyval QObject wrapped QAPI text --> parser --> QObject --> in keyval qobj. --> visit --> object input visitor 3. "string": text wrapped QAPI text -------------------------> in string --> visit --> object input visitor 4. QemuOpts: opts QemOpts wrapped QAPI text --> parser --> QemuOpts --> in options --> visit --> object visitor In the JSON pipeline, the parser produces an appropriately typed QObject, and the qobject input visitor checks it against the schema. Dotted keys syntax doesn't tell us which scalar type to use, so the parser uses QString for all scalars. We then have to use a special keyval qobject input visitor that expects strings instead of appropriately typed scalars. If the resulting QAPI object contains 'any' types, then those remain unconverted. To visit them, you must use the keyval qobject input visitor, not the plan one. These pipelines share a tail: Input wrapped QAPI in appropriate --> visit --> object input visitor The (still few) QAPIfied CLI options exploit this: if the option argument looks like JSON, we feed it to the JSON half of the joint pipeline, else to the keyval half. The entire part before "visit" is qobject_input_visitor_new_str(): it returns the QObject wrapped in the appropriate visitor. To go from QObject wrapped in visitor to a QAPI object of type T, we generally call generated function visit_type_T(). The string pipeline is used chiefly for QOM. The visit part is generally manual, in the property set() method. The string visitor is seriously limited: it supports only scalars and lists of certain integers. The QemuOpts pipeline is used by a few CLI options and HMP commands, such as -netdev, -numa, -object. It is also almost as seriously limited. The code for "lists of certain integers" will make your eyes bleed. I'd love to replace the string and the options pipeline by the keyval pipeline.