qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Daniel P. Berrangé" <berrange@redhat.com>
To: Markus Armbruster <armbru@redhat.com>
Cc: Victor Toso <victortoso@redhat.com>,
	qemu-devel@nongnu.org, John Snow <jsnow@redhat.com>
Subject: Re: [PATCH v1 1/9] qapi: golang: Generate qapi's enum types in Go
Date: Thu, 28 Sep 2023 15:34:44 +0100	[thread overview]
Message-ID: <ZRWPBJKASLmmK/f/@redhat.com> (raw)
In-Reply-To: <87cyy2tm48.fsf@pond.sub.org>

On Thu, Sep 28, 2023 at 04:20:55PM +0200, Markus Armbruster wrote:
> Daniel P. Berrangé <berrange@redhat.com> writes:
> 
> > On Wed, Sep 27, 2023 at 01:25:36PM +0200, Victor Toso wrote:
> >> This patch handles QAPI enum types and generates its equivalent in Go.
> >> 
> >> Basically, Enums are being handled as strings in Golang.
> >> 
> >> 1. For each QAPI enum, we will define a string type in Go to be the
> >>    assigned type of this specific enum.
> >> 
> >> 2. Naming: CamelCase will be used in any identifier that we want to
> >>    export [0], which is everything.
> >> 
> >> [0] https://go.dev/ref/spec#Exported_identifiers
> >> 
> >> Example:
> >> 
> >> qapi:
> >>   | { 'enum': 'DisplayProtocol',
> >>   |   'data': [ 'vnc', 'spice' ] }
> >> 
> >> go:
> >>   | type DisplayProtocol string
> >>   |
> >>   | const (
> >>   |     DisplayProtocolVnc   DisplayProtocol = "vnc"
> >>   |     DisplayProtocolSpice DisplayProtocol = "spice"
> >>   | )
> >> 
> >> Signed-off-by: Victor Toso <victortoso@redhat.com>
> >> ---
> >>  scripts/qapi/golang.py | 140 +++++++++++++++++++++++++++++++++++++++++
> >>  scripts/qapi/main.py   |   2 +
> >>  2 files changed, 142 insertions(+)
> >>  create mode 100644 scripts/qapi/golang.py
> >> 
> >> diff --git a/scripts/qapi/golang.py b/scripts/qapi/golang.py
> >> new file mode 100644
> >> index 0000000000..87081cdd05
> >> --- /dev/null
> >> +++ b/scripts/qapi/golang.py
> >> @@ -0,0 +1,140 @@
> >> +"""
> >> +Golang QAPI generator
> >> +"""
> >> +# Copyright (c) 2023 Red Hat Inc.
> >> +#
> >> +# Authors:
> >> +#  Victor Toso <victortoso@redhat.com>
> >> +#
> >> +# This work is licensed under the terms of the GNU GPL, version 2.
> >> +# See the COPYING file in the top-level directory.
> >> +
> >> +# due QAPISchemaVisitor interface
> >> +# pylint: disable=too-many-arguments
> >> +
> >> +# Just for type hint on self
> >> +from __future__ import annotations
> >> +
> >> +import os
> >> +from typing import List, Optional
> >> +
> >> +from .schema import (
> >> +    QAPISchema,
> >> +    QAPISchemaType,
> >> +    QAPISchemaVisitor,
> >> +    QAPISchemaEnumMember,
> >> +    QAPISchemaFeature,
> >> +    QAPISchemaIfCond,
> >> +    QAPISchemaObjectType,
> >> +    QAPISchemaObjectTypeMember,
> >> +    QAPISchemaVariants,
> >> +)
> >> +from .source import QAPISourceInfo
> >> +
> >> +TEMPLATE_ENUM = '''
> >> +type {name} string
> >> +const (
> >> +{fields}
> >> +)
> >> +'''
> >> +
> >> +
> >> +def gen_golang(schema: QAPISchema,
> >> +               output_dir: str,
> >> +               prefix: str) -> None:
> >> +    vis = QAPISchemaGenGolangVisitor(prefix)
> >> +    schema.visit(vis)
> >> +    vis.write(output_dir)
> >> +
> >> +
> >> +def qapi_to_field_name_enum(name: str) -> str:
> >> +    return name.title().replace("-", "")
> >> +
> >> +
> >> +class QAPISchemaGenGolangVisitor(QAPISchemaVisitor):
> >> +
> >> +    def __init__(self, _: str):
> >> +        super().__init__()
> >> +        types = ["enum"]
> >> +        self.target = {name: "" for name in types}
> >> +        self.schema = None
> >> +        self.golang_package_name = "qapi"
> >> +
> >> +    def visit_begin(self, schema):
> >> +        self.schema = schema
> >> +
> >> +        # Every Go file needs to reference its package name
> >> +        for target in self.target:
> >> +            self.target[target] = f"package {self.golang_package_name}\n"
> >> +
> >> +    def visit_end(self):
> >> +        self.schema = None
> >> +
> >> +    def visit_object_type(self: QAPISchemaGenGolangVisitor,
> >> +                          name: str,
> >> +                          info: Optional[QAPISourceInfo],
> >> +                          ifcond: QAPISchemaIfCond,
> >> +                          features: List[QAPISchemaFeature],
> >> +                          base: Optional[QAPISchemaObjectType],
> >> +                          members: List[QAPISchemaObjectTypeMember],
> >> +                          variants: Optional[QAPISchemaVariants]
> >> +                          ) -> None:
> >> +        pass
> >> +
> >> +    def visit_alternate_type(self: QAPISchemaGenGolangVisitor,
> >> +                             name: str,
> >> +                             info: Optional[QAPISourceInfo],
> >> +                             ifcond: QAPISchemaIfCond,
> >> +                             features: List[QAPISchemaFeature],
> >> +                             variants: QAPISchemaVariants
> >> +                             ) -> None:
> >> +        pass
> >> +
> >> +    def visit_enum_type(self: QAPISchemaGenGolangVisitor,
> >> +                        name: str,
> >> +                        info: Optional[QAPISourceInfo],
> >> +                        ifcond: QAPISchemaIfCond,
> >> +                        features: List[QAPISchemaFeature],
> >> +                        members: List[QAPISchemaEnumMember],
> >> +                        prefix: Optional[str]
> >> +                        ) -> None:
> >> +
> >> +        value = qapi_to_field_name_enum(members[0].name)
> >> +        fields = ""
> >> +        for member in members:
> >> +            value = qapi_to_field_name_enum(member.name)
> >> +            fields += f'''\t{name}{value} {name} = "{member.name}"\n'''
> >> +
> >> +        self.target["enum"] += TEMPLATE_ENUM.format(name=name, fields=fields[:-1])
> >
> > Here you are formatting the enums as you visit them, appending to
> > the output buffer. The resulting enums appear in whatever order we
> > visited them with, which is pretty arbitrary.
> 
> We visit in source order, not in arbitrary order.

I meant arbitrary in the sense that us developers just add new
QAPI types pretty much anywhere we feel like it in the .qapi
files.

> 
> > Browsing the generated Go code to understand it, I find myself
> > wishing that it was emitted in alphabetical order.
> 
> If that's easier to read in generated Go, then I suspect it would also
> be easier to read in the QAPI schema and in generated C.

Yes, although C has some ordering constraints on things being
declared, so it would be a bit harder to do this in C.


With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



  reply	other threads:[~2023-09-28 14:35 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-27 11:25 [PATCH v1 0/9] qapi-go: add generator for Golang interface Victor Toso
2023-09-27 11:25 ` [PATCH v1 1/9] qapi: golang: Generate qapi's enum types in Go Victor Toso
2023-09-28 13:52   ` Daniel P. Berrangé
2023-09-28 14:20     ` Markus Armbruster
2023-09-28 14:34       ` Daniel P. Berrangé [this message]
2023-09-29 12:07     ` Victor Toso
2023-10-02 19:07   ` John Snow
2023-10-02 20:09     ` John Snow
2023-10-04 12:43       ` Victor Toso
2023-10-04 16:23         ` John Snow
2023-10-04 12:28     ` Victor Toso
2023-09-27 11:25 ` [PATCH v1 2/9] qapi: golang: Generate qapi's alternate " Victor Toso
2023-09-28 14:51   ` Daniel P. Berrangé
2023-09-29 12:23     ` Victor Toso
2023-09-29 12:37       ` Daniel P. Berrangé
2023-10-02 21:48         ` John Snow
2023-10-04 17:01           ` Victor Toso
2023-10-02 20:36   ` John Snow
2023-10-04 16:46     ` Victor Toso
2023-09-27 11:25 ` [PATCH v1 3/9] qapi: golang: Generate qapi's struct " Victor Toso
2023-09-28 14:06   ` Daniel P. Berrangé
2023-09-29 13:29     ` Victor Toso
2023-09-29 13:33       ` Daniel P. Berrangé
2023-09-27 11:25 ` [PATCH v1 4/9] qapi: golang: structs: Address 'null' members Victor Toso
2023-09-27 11:25 ` [PATCH v1 5/9] qapi: golang: Generate qapi's union types in Go Victor Toso
2023-09-28 14:21   ` Daniel P. Berrangé
2023-09-29 13:41     ` Victor Toso
2023-10-11 13:27       ` Victor Toso
2023-09-27 11:25 ` [PATCH v1 6/9] qapi: golang: Generate qapi's event " Victor Toso
2023-09-27 11:25 ` [PATCH v1 7/9] qapi: golang: Generate qapi's command " Victor Toso
2023-09-28 14:32   ` Daniel P. Berrangé
2023-09-29 13:53     ` Victor Toso
2023-10-14 14:26     ` Victor Toso
2023-09-27 11:25 ` [PATCH v1 8/9] qapi: golang: Add CommandResult type to Go Victor Toso
2023-09-28 15:03   ` Daniel P. Berrangé
2023-09-29 13:55     ` Victor Toso
2023-09-27 11:25 ` [PATCH v1 9/9] docs: add notes on Golang code generator Victor Toso
2023-09-28 13:22   ` Daniel P. Berrangé
2023-09-29 12:00     ` Victor Toso
2023-09-27 11:38 ` [PATCH v1 0/9] qapi-go: add generator for Golang interface Victor Toso
2023-09-28 13:40 ` Daniel P. Berrangé
2023-09-28 13:54   ` Daniel P. Berrangé
2023-09-29 14:08     ` Victor Toso
2023-09-29 14:17   ` Victor Toso

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=ZRWPBJKASLmmK/f/@redhat.com \
    --to=berrange@redhat.com \
    --cc=armbru@redhat.com \
    --cc=jsnow@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=victortoso@redhat.com \
    /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).