new file mode 100644
@@ -0,0 +1,134 @@
+"""
+Golang QAPI generator
+"""
+# Copyright (c) 2022 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.
+
+# 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
+
+
+class QAPISchemaGenGolangVisitor(QAPISchemaVisitor):
+
+ def __init__(self, prefix: str):
+ super().__init__()
+ self.target = {name: "" for name in ["enum"]}
+ 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"] += f'''
+type {name} string
+const (
+{fields[:-1]}
+)
+'''
+
+ def visit_array_type(self, name, info, ifcond, element_type):
+ pass
+
+ def visit_command(self,
+ name: str,
+ info: Optional[QAPISourceInfo],
+ ifcond: QAPISchemaIfCond,
+ features: List[QAPISchemaFeature],
+ arg_type: Optional[QAPISchemaObjectType],
+ ret_type: Optional[QAPISchemaType],
+ gen: bool,
+ success_response: bool,
+ boxed: bool,
+ allow_oob: bool,
+ allow_preconfig: bool,
+ coroutine: bool) -> None:
+ pass
+
+ def visit_event(self, name, info, ifcond, features, arg_type, boxed):
+ pass
+
+ def write(self, output_dir: str) -> None:
+ for module_name, content in self.target.items():
+ go_module = module_name + "s.go"
+ go_dir = "go"
+ pathname = os.path.join(output_dir, go_dir, go_module)
+ odir = os.path.dirname(pathname)
+ os.makedirs(odir, exist_ok=True)
+
+ with open(pathname, "w") as outfile:
+ outfile.write(content)
+
+
+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("-", "")
@@ -15,6 +15,7 @@
from .common import must_match
from .error import QAPIError
from .events import gen_events
+from .golang import gen_golang
from .introspect import gen_introspect
from .schema import QAPISchema
from .types import gen_types
@@ -54,6 +55,7 @@ def generate(schema_file: str,
gen_events(schema, output_dir, prefix)
gen_introspect(schema, output_dir, prefix, unmask)
+ gen_golang(schema, output_dir, prefix)
def main() -> int:
"""
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 | 134 +++++++++++++++++++++++++++++++++++++++++ scripts/qapi/main.py | 2 + 2 files changed, 136 insertions(+) create mode 100644 scripts/qapi/golang.py