Skip to content

Several fixes for XenServer SDK for Go #5687

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ocaml/sdk-gen/go/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ Extract the contents of this archive.

A. Navigate to the extracted `XenServer-SDK\XenServerGo\src` directory and copy the whole folder `src` into your Go project directory.

B. To use XenServer Go SDK as a local Go module, update one line into the `go.mod` file under your Go project:
B. To use the XenServer SDK for Go as a local Go module, include the following line into the `go.mod` file under your Go project:

```
replace xenapi => ./src
```
You can then import this XenServer SDK Go module with the following command:
You can then import the XenServer SDK for Go with the following command:

```
import "xenapi"
Expand Down
29 changes: 29 additions & 0 deletions ocaml/sdk-gen/go/autogen/src/jsonrpc_client.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,32 @@
/*
* Copyright (c) Cloud Software Group, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1) Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2) Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package xenapi

import (
Expand Down
5 changes: 4 additions & 1 deletion ocaml/sdk-gen/go/gen_go_binding.ml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ open Gen_go_helper
let render_enums enums destdir =
let header =
render_template "FileHeader.mustache"
(`O [("modules", `Null)])
(`O [("modules", `Null); licence])
~newline:true ()
in
let enums = render_template "Enum.mustache" enums () |> String.trim in
Expand All @@ -36,6 +36,7 @@ let render_api_versions destdir =
; ("items", `A (List.map name ["errors"; "fmt"]))
]
)
; licence
]
in
let rendered =
Expand All @@ -55,6 +56,7 @@ let render_api_messages_and_errors destdir =
("api_errors", `A Json.api_errors)
; ("api_messages", `A Json.api_messages)
; ("modules", `Null)
; licence
]
in
let header = render_template "FileHeader.mustache" obj ~newline:true () in
Expand Down Expand Up @@ -83,6 +85,7 @@ let render_convert_header () =
)
]
)
; licence
]
in
render_template "FileHeader.mustache" obj ~newline:true ()
Expand Down
151 changes: 103 additions & 48 deletions ocaml/sdk-gen/go/gen_go_helper.ml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ let templates_dir = "templates"

let ( // ) = Filename.concat

let licence = ("licence", `String Licence.bsd_two_clause)

let acronyms =
[
"id"
Expand Down Expand Up @@ -316,38 +318,6 @@ module Json = struct
| [] ->
failwith "Empty params group should not exist."

let of_param param =
let name_internal name =
let name = snake_to_camel ~internal:true name in
match name with "type" -> "typeKey" | "interface" -> "inter" | _ -> name
in
let suffix_of_type = suffix_of_type param.param_type in
let t, _e = string_of_ty_with_enums param.param_type in
let name = param.param_name in
[
("is_session_id", `Bool (name = "session_id"))
; ("type", `String t)
; ("name", `String name)
; ("name_internal", `String (name_internal name))
; ("doc", `String param.param_doc)
; ("func_name_suffix", `String suffix_of_type)
]

(* We use ',' to seprate params in Go function, we should ignore ',' before first param,
for example `func(a type1, b type2)` is wanted rather than `func(, a type1, b type2)`.
*)
let of_params = function
| head :: rest ->
let head = `O (("first", `Bool true) :: of_param head) in
let rest =
List.map
(fun item -> `O (("first", `Bool false) :: of_param item))
rest
in
head :: rest
| [] ->
[]

let of_error e = `O [("name", `String e.err_name); ("doc", `String e.err_doc)]

let of_errors = function
Expand Down Expand Up @@ -391,10 +361,81 @@ module Json = struct
else
method_name ^ string_of_int (List.length params)

(* Since the param of `session *Session` isn't needed in functions of session object,
we add a special "func_params" field for session object to ignore `session *Session`.*)
let addtion_info_of_session method_name params latest =
let add_session_info method_name =
module ParamInfo = struct
type param_info = {
typ: string
; func_param: string
; name: string
; name_internal: string
; name_in_serialize_call: string
; doc: string
; func_name_suffix: string
}

let to_param_info ~is_sess_func param =
let suffix_of_type = suffix_of_type param.param_type in
let t, _e = string_of_ty_with_enums param.param_type in
let name = param.param_name in
let is_session_id = name = "session_id" in
let internal_name =
let name' = snake_to_camel ~internal:true name in
match name' with
| "type" ->
"typeKey"
| "interface" ->
"inter"
| _ ->
name'
in
let func_param =
match (is_sess_func, is_session_id) with
| true, _ | false, false ->
Printf.sprintf "%s %s" internal_name t
| false, true ->
"session *Session"
in
let name_in_serialize_call =
match (is_sess_func, is_session_id) with
| false, false | true, false ->
internal_name
| true, true ->
"class.ref"
| false, true ->
"session.ref"
in
{
typ= t
; func_param
; name
; name_internal= internal_name
; name_in_serialize_call
; doc= param.param_doc
; func_name_suffix= suffix_of_type
}
end

let of_param_info param_info =
let open ParamInfo in
let p = param_info in
`O
[
("type", `String p.typ)
; ("name", `String p.name)
; ("name_internal", `String p.name_internal)
; ("name_in_serialize_call", `String p.name_in_serialize_call)
; ("doc", `String p.doc)
; ("func_name_suffix", `String p.func_name_suffix)
]

let of_param ~is_sess_func param =
ParamInfo.to_param_info ~is_sess_func param |> of_param_info

let to_func_params params =
List.map (fun p -> p.ParamInfo.func_param) params |> String.concat ", "

let diverse_info_of_session method_name params msg_session latest =
let is_sess_func = true in
let session_info method_name =
match method_name with
| "login_with_password" | "slave_local_login_with_password" ->
[("session_login", `Bool true); ("session_logout", `Bool false)]
Expand All @@ -403,21 +444,35 @@ module Json = struct
| _ ->
[("session_login", `Bool false); ("session_logout", `Bool false)]
in
let name = method_name_exported method_name params latest in
("func_params", `A (of_params params))
(* In a session function, the session is from the instance rather than parameter list *)
let params' = if msg_session then List.tl params else params in
let name = method_name_exported method_name params' latest in
let func_params =
List.map (ParamInfo.to_param_info ~is_sess_func) params' |> to_func_params
in
("func_params", `String func_params)
:: ("params", `A (List.map (of_param ~is_sess_func) params))
:: ("method_name_exported", `String name)
:: add_session_info method_name
:: session_info method_name

let addtion_info msg params latest =
(* This is for the variables which are diverse for different messages *)
let diverse_info msg params latest =
let method_name = msg.msg_name in
match (String.lowercase_ascii msg.msg_obj_name, msg.msg_session) with
| "session", true ->
addtion_info_of_session method_name (List.tl params) latest
| "session", false ->
addtion_info_of_session method_name params latest
match String.lowercase_ascii msg.msg_obj_name with
| "session" ->
diverse_info_of_session method_name params msg.msg_session latest
| _ ->
let is_sess_func = false in
let func_params =
List.map (ParamInfo.to_param_info ~is_sess_func) params
|> to_func_params
in
let name = method_name_exported method_name params latest in
[("method_name_exported", `String name)]
[
("func_params", `String func_params)
; ("params", `A (List.map (of_param ~is_sess_func) params))
; ("method_name_exported", `String name)
]

let messages_of_obj obj =
let ctor_fields = ctor_fields_of_obj obj in
Expand All @@ -431,14 +486,13 @@ module Json = struct
; ("class_name_exported", `String (snake_to_camel obj.name))
; ("description", desc_of_msg msg ctor_fields)
; ("result", of_result obj msg)
; ("params", `A (of_params params))
; ("errors", of_errors msg.msg_errors)
; ("has_error", `Bool (msg.msg_errors <> []))
; ("async", `Bool msg.msg_async)
; ("version", `String rel_version)
]
in
`O (base_assoc_list @ addtion_info msg params latest)
`O (base_assoc_list @ diverse_info msg params latest)
in
msg |> group_params |> List.map of_message
)
Expand Down Expand Up @@ -479,6 +533,7 @@ module Json = struct
; ("modules", modules)
; ("messages", `A (messages_of_obj obj))
; ("option", `A (of_options types))
; licence
]
in
let assoc_list = base_assoc_list @ get_event_session_value obj.name in
Expand Down
2 changes: 2 additions & 0 deletions ocaml/sdk-gen/go/gen_go_helper.mli
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

val ( // ) : string -> string -> string

val licence : string * Mustache.Json.value

val snake_to_camel : ?internal:bool -> string -> string

val render_template :
Expand Down
3 changes: 2 additions & 1 deletion ocaml/sdk-gen/go/templates/FileHeader.mustache
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{{{licence}}}
package xenapi
{{#modules}}
{{#import}}
Expand All @@ -8,4 +9,4 @@ import (
{{/items}}
)
{{/import}}
{{/modules}}
{{/modules}}
10 changes: 5 additions & 5 deletions ocaml/sdk-gen/go/templates/Methods.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
{{#errors}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a licence placeholder in this file or SessionMethod.mustache, was it forgotten?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The license placeholder is added in FileHeader.mustache. This header is for all generated .go files except jsonrpc_client.go

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked all generated .go files, all contained the license in file header.

// {{name}} - {{doc}}
{{/errors}}
func ({{name_internal}}) {{method_name_exported}}({{#params}}{{#first}}session *Session{{/first}}{{^first}}, {{name_internal}} {{type}}{{/first}}{{/params}}) ({{#result}}retval {{type}}, {{/result}}err error) {
func ({{name_internal}}) {{method_name_exported}}({{func_params}}) ({{#result}}retval {{type}}, {{/result}}err error) {
method := "{{class_name}}.{{method_name}}"
{{#params}}
{{name_internal}}Arg, err := serialize{{func_name_suffix}}(fmt.Sprintf("%s(%s)", method, "{{name}}"), {{#first}}session.ref{{/first}}{{^first}}{{name_internal}}{{/first}})
{{name_internal}}Arg, err := serialize{{func_name_suffix}}(fmt.Sprintf("%s(%s)", method, "{{name}}"), {{name_in_serialize_call}})
if err != nil {
return
}
Expand All @@ -36,10 +36,10 @@ func ({{name_internal}}) {{method_name_exported}}({{#params}}{{#first}}session *
{{#errors}}
// {{name}} - {{doc}}
{{/errors}}
func ({{name_internal}}) Async{{method_name_exported}}({{#params}}{{#first}}session *Session{{/first}}{{^first}}, {{name_internal}} {{type}}{{/first}}{{/params}}) (retval TaskRef, err error) {
func ({{name_internal}}) Async{{method_name_exported}}({{func_params}}) (retval TaskRef, err error) {
method := "Async.{{class_name}}.{{method_name}}"
{{#params}}
{{name_internal}}Arg, err := serialize{{func_name_suffix}}(fmt.Sprintf("%s(%s)", method, "{{name}}"), {{#first}}session.ref{{/first}}{{^first}}{{name_internal}}{{/first}})
{{name_internal}}Arg, err := serialize{{func_name_suffix}}(fmt.Sprintf("%s(%s)", method, "{{name}}"), {{name_in_serialize_call}})
if err != nil {
return
}
Expand All @@ -53,4 +53,4 @@ func ({{name_internal}}) Async{{method_name_exported}}({{#params}}{{#first}}sess
}

{{/async}}
{{/messages}}
{{/messages}}
10 changes: 5 additions & 5 deletions ocaml/sdk-gen/go/templates/SessionMethod.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
{{#errors}}
// {{name}} - {{doc}}
{{/errors}}
func (class *Session) {{method_name_exported}}({{#func_params}}{{^first}}, {{/first}}{{name_internal}} {{type}}{{/func_params}}) ({{#result}}retval {{type}}, {{/result}}err error) {
func (class *Session) {{method_name_exported}}({{func_params}}) ({{#result}}retval {{type}}, {{/result}}err error) {
method := "{{class_name}}.{{method_name}}"
{{#params}}
{{name_internal}}Arg, err := serialize{{func_name_suffix}}(fmt.Sprintf("%s(%s)", method, "{{name}}"), {{#is_session_id}}class.ref{{/is_session_id}}{{^is_session_id}}{{name_internal}}{{/is_session_id}})
{{name_internal}}Arg, err := serialize{{func_name_suffix}}(fmt.Sprintf("%s(%s)", method, "{{name}}"), {{name_in_serialize_call}})
if err != nil {
return
}
Expand Down Expand Up @@ -46,10 +46,10 @@ func (class *Session) {{method_name_exported}}({{#func_params}}{{^first}}, {{/fi
{{#errors}}
// {{name}} - {{doc}}
{{/errors}}
func (class *Session) Async{{method_name_exported}}({{#func_params}}{{^first}}, {{/first}}{{name_internal}} {{type}}{{/func_params}}) (retval TaskRef, err error) {
func (class *Session) Async{{method_name_exported}}({{func_params}}) (retval TaskRef, err error) {
method := "Async.{{class_name}}.{{method_name}}"
{{#params}}
{{name_internal}}Arg, err := serialize{{func_name_suffix}}(fmt.Sprintf("%s(%s)", method, "{{name}}"), {{#is_session_id}}class.ref{{/is_session_id}}{{^is_session_id}}{{name_internal}}{{/is_session_id}})
{{name_internal}}Arg, err := serialize{{func_name_suffix}}(fmt.Sprintf("%s(%s)", method, "{{name}}"), {{name_in_serialize_call}})
if err != nil {
return
}
Expand All @@ -63,4 +63,4 @@ func (class *Session) Async{{method_name_exported}}({{#func_params}}{{^first}},
}

{{/async}}
{{/messages}}
{{/messages}}
Loading
Loading