This patch handles QAPI command types and generates data structures in Go that handles it.
Note that command's id is part of the first layer of unmarshal, so it is a member of protocol.go's Message type. qapi: | ## | # @add-fd: | # | # Add a file descriptor, that was passed via SCM rights, to an fd set. | # | # @fdset-id: The ID of the fd set to add the file descriptor to. | # | # @opaque: A free-form string that can be used to describe the fd. | # | # Returns: | # @AddfdInfo | # | # Errors: | # - If file descriptor was not received, GenericError | # - If @fdset-id is a negative value, GenericError | # | # .. note:: The list of fd sets is shared by all monitor connections. | # | # .. note:: If @fdset-id is not specified, a new fd set will be | # created. | # | # Since: 1.2 | # | # .. qmp-example:: | # | # -> { "execute": "add-fd", "arguments": { "fdset-id": 1 } } | # <- { "return": { "fdset-id": 1, "fd": 3 } } | ## | { 'command': 'add-fd', | 'data': { '*fdset-id': 'int', | '*opaque': 'str' }, | 'returns': 'AddfdInfo' } go: | // Add a file descriptor, that was passed via SCM rights, to an fd | // set. | // | // Returns: @AddfdInfo | // | // Errors: - If file descriptor was not received, GenericError - | // If @fdset-id is a negative value, GenericError | // | // .. note:: The list of fd sets is shared by all monitor connections. | // .. note:: If @fdset-id is not specified, a new fd set will be | // created. | // | // Since: 1.2 | // | // .. qmp-example:: -> { "execute": "add-fd", "arguments": { | // "fdset-id": 1 } } <- { "return": { "fdset-id": 1, "fd": 3 } } | type AddFdCommand struct { | // The ID of the fd set to add the file descriptor to. | FdsetId *int64 `json:"fdset-id,omitempty"` | // A free-form string that can be used to describe the fd. | Opaque *string `json:"opaque,omitempty"` | } Signed-off-by: Victor Toso <victort...@redhat.com> --- scripts/qapi/golang/golang.py | 52 +++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/scripts/qapi/golang/golang.py b/scripts/qapi/golang/golang.py index b9a2c47137..a14970fb1f 100644 --- a/scripts/qapi/golang/golang.py +++ b/scripts/qapi/golang/golang.py @@ -316,7 +316,7 @@ def qapi_to_go_type_name(name: str, meta: Optional[str] = None) -> str: name += "".join(word.title() for word in words[1:]) # Handle specific meta suffix - types = ["event"] + types = ["event", "command"] if meta in types: name = name[:-3] if name.endswith("Arg") else name name += meta.title().replace(" ", "") @@ -1009,6 +1009,15 @@ def generate_template_alternate( return "\n" + content +def generate_template_command(commands: dict[str, Tuple[str, str]]) -> str: + content = "" + for name in sorted(commands): + type_name, gocode = commands[name] + content += gocode + + return content + + def generate_template_event(events: dict[str, Tuple[str, str]]) -> (str, str): content = "" methods = "" @@ -1069,6 +1078,7 @@ def __init__(self, _: str): # Map each qapi type to the necessary Go imports types = { "alternate": ["encoding/json", "errors", "fmt"], + "command": [], "enum": [], "event": [], "struct": ["encoding/json"], @@ -1080,6 +1090,7 @@ def __init__(self, _: str): self.schema: QAPISchema self.events: dict[str, Tuple[str, str]] = {} + self.commands: dict[str, Tuple[str, str]] = {} self.golang_package_name = "qapi" self.duplicate = list(gofiles) self.enums: dict[str, str] = {} @@ -1140,6 +1151,8 @@ def visit_end(self) -> None: self.types["event"] += evtype self.interfaces["event"] += eviface + self.types["command"] += generate_template_command(self.commands) + def visit_object_type( self, name: str, @@ -1286,7 +1299,42 @@ def visit_command( allow_preconfig: bool, coroutine: bool, ) -> None: - pass + assert name == info.defn_name + assert name not in self.commands + + type_name = qapi_to_go_type_name(name, info.defn_meta) + + doc = self.docmap.get(name, None) + type_doc, _ = qapi_to_golang_struct_docs(doc) + + content = "" + if boxed or not arg_type or not qapi_name_is_object(arg_type.name): + args: List[dict[str:str]] = [] + if arg_type: + args.append( + { + "name": f"{arg_type.name}", + } + ) + content += string_to_code( + generate_struct_type(type_name, type_doc=type_doc, args=args) + ) + else: + assert isinstance(arg_type, QAPISchemaObjectType) + content += string_to_code( + qapi_to_golang_struct( + self, + name, + arg_type.info, + arg_type.ifcond, + arg_type.features, + arg_type.base, + arg_type.members, + arg_type.branches, + ) + ) + + self.commands[name] = (type_name, content) def visit_event( self, -- 2.48.1