aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/varlink/go/cmd/varlink-go-interface-generator
diff options
context:
space:
mode:
authorbaude <bbaude@redhat.com>2018-03-26 09:39:14 -0500
committerAtomic Bot <atomic-devel@projectatomic.io>2018-04-23 14:29:45 +0000
commit8493dba23c73617d9529b7ca13b400d50ac6f455 (patch)
treec0de0c67334b9fa7166e01cae95dc560c1e2455a /vendor/github.com/varlink/go/cmd/varlink-go-interface-generator
parentcf1d884ffa45b342f38a78189bbd86186ce6cbfe (diff)
downloadpodman-8493dba23c73617d9529b7ca13b400d50ac6f455.tar.gz
podman-8493dba23c73617d9529b7ca13b400d50ac6f455.tar.bz2
podman-8493dba23c73617d9529b7ca13b400d50ac6f455.zip
Initial varlink implementation
Signed-off-by: baude <bbaude@redhat.com> Closes: #627 Approved by: mheon
Diffstat (limited to 'vendor/github.com/varlink/go/cmd/varlink-go-interface-generator')
-rw-r--r--vendor/github.com/varlink/go/cmd/varlink-go-interface-generator/generator_test.go85
-rw-r--r--vendor/github.com/varlink/go/cmd/varlink-go-interface-generator/main.go294
2 files changed, 379 insertions, 0 deletions
diff --git a/vendor/github.com/varlink/go/cmd/varlink-go-interface-generator/generator_test.go b/vendor/github.com/varlink/go/cmd/varlink-go-interface-generator/generator_test.go
new file mode 100644
index 000000000..aa3a8565f
--- /dev/null
+++ b/vendor/github.com/varlink/go/cmd/varlink-go-interface-generator/generator_test.go
@@ -0,0 +1,85 @@
+package main
+
+import (
+ "strings"
+ "testing"
+)
+
+func expect(t *testing.T, expected string, returned string) {
+ if strings.Compare(returned, expected) != 0 {
+ t.Fatalf("Expected(%d): `%s`\nGot(%d): `%s`\n",
+ len(expected), expected,
+ len(returned), returned)
+ }
+}
+
+func TestIDLParser(t *testing.T) {
+ pkgname, b, err := generateTemplate(`
+# Interface to jump a spacecraft to another point in space. The
+# FTL Drive is the propulsion system to achieve faster-than-light
+# travel through space. A ship making a properly calculated
+# jump can arrive safely in planetary orbit, or alongside other
+# ships or spaceborne objects.
+interface org.example.ftl
+
+# The current state of the FTL drive and the amount of fuel
+# available to jump.
+type DriveCondition (
+ state: (idle, spooling, busy),
+ booster: bool,
+ active_engines: [](id: int, state: bool),
+ tylium_level: int
+)
+
+# Speed, trajectory and jump duration is calculated prior to
+# activating the FTL drive.
+type DriveConfiguration (
+ speed: int,
+ trajectory: int,
+ duration: int
+)
+
+# The galactic coordinates use the Sun as the origin. Galactic
+# longitude is measured with primary direction from the Sun to
+# the center of the galaxy in the galactic plane, while the
+# galactic latitude measures the angle of the object above the
+# galactic plane.
+type Coordinate (
+ longitude: float,
+ latitude: float,
+ distance: int
+)
+
+# Monitor the drive. The method will reply with an update whenever
+# the drive's state changes
+method Monitor() -> (condition: DriveCondition)
+
+# Calculate the drive's jump parameters from the current
+# position to the target position in the galaxy
+method CalculateConfiguration(
+ current: Coordinate,
+ target: Coordinate
+) -> (configuration: DriveConfiguration)
+
+# Jump to the calculated point in space
+method Jump(configuration: DriveConfiguration) -> ()
+
+# There is not enough tylium to jump with the given parameters
+error NotEnoughEnergy ()
+
+# The supplied parameters are outside the supported range
+error ParameterOutOfRange (field: string)
+
+# some more coverage
+method Foo(interface: string) -> (ret: (go: string, switch: bool, more: (t:bool, f:bool)))
+ `)
+
+ if err != nil {
+ t.Fatalf("Error parsing %v", err)
+ }
+ expect(t, "orgexampleftl", pkgname)
+ if len(b) <= 0 {
+ t.Fatal("No generated go source")
+ }
+ // FIXME: compare b.String() against expected output
+}
diff --git a/vendor/github.com/varlink/go/cmd/varlink-go-interface-generator/main.go b/vendor/github.com/varlink/go/cmd/varlink-go-interface-generator/main.go
new file mode 100644
index 000000000..1bcdb78de
--- /dev/null
+++ b/vendor/github.com/varlink/go/cmd/varlink-go-interface-generator/main.go
@@ -0,0 +1,294 @@
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path"
+ "strings"
+
+ "github.com/varlink/go/varlink/idl"
+)
+
+var goKeywords = map[string]struct{}{
+ "break": {},
+ "case": {},
+ "chan": {},
+ "const": {},
+ "continue": {},
+ "default": {},
+ "defer": {},
+ "else": {},
+ "fallthrough": {},
+ "for": {},
+ "func": {},
+ "go": {},
+ "goto": {},
+ "if": {},
+ "import": {},
+ "interface": {},
+ "map": {},
+ "package": {},
+ "range": {},
+ "return": {},
+ "select": {},
+ "struct": {},
+ "switch": {},
+ "type": {},
+ "var": {},
+}
+
+func sanitizeGoName(name string) string {
+ if _, ok := goKeywords[name]; !ok {
+ return name
+ }
+ return name + "_"
+}
+
+func writeType(b *bytes.Buffer, t *idl.Type, json bool, ident int) {
+ switch t.Kind {
+ case idl.TypeBool:
+ b.WriteString("bool")
+
+ case idl.TypeInt:
+ b.WriteString("int64")
+
+ case idl.TypeFloat:
+ b.WriteString("float64")
+
+ case idl.TypeString, idl.TypeEnum:
+ b.WriteString("string")
+
+ case idl.TypeArray:
+ b.WriteString("[]")
+ writeType(b, t.ElementType, json, ident)
+
+ case idl.TypeMaybe:
+ b.WriteString("*")
+ writeType(b, t.ElementType, json, ident)
+
+ case idl.TypeAlias:
+ b.WriteString(t.Alias)
+
+ case idl.TypeStruct:
+ b.WriteString("struct{\n")
+ for _, field := range t.Fields {
+ for i := 0; i < ident+1; i++ {
+ b.WriteString("\t")
+ }
+
+ b.WriteString(strings.Title(field.Name) + " ")
+ writeType(b, field.Type, json, ident+1)
+ if json {
+ b.WriteString(" `json:\"" + field.Name + "\"`")
+ }
+ b.WriteString("\n")
+ }
+ for i := 0; i < ident; i++ {
+ b.WriteString("\t")
+ }
+ b.WriteString("}")
+ }
+}
+
+func generateTemplate(description string) (string, []byte, error) {
+ description = strings.TrimRight(description, "\n")
+
+ midl, err := idl.New(description)
+ if err != nil {
+ return "", nil, err
+ }
+
+ pkgname := strings.Replace(midl.Name, ".", "", -1)
+
+ var b bytes.Buffer
+ b.WriteString("// Generated with github.com/varlink/go/cmd/varlink-go-interface-generator\n")
+ b.WriteString("package " + pkgname + "\n\n")
+ b.WriteString(`import "github.com/varlink/go/varlink"` + "\n\n")
+
+ // Type declarations
+ for _, a := range midl.Aliases {
+ b.WriteString("type " + a.Name + " ")
+ writeType(&b, a.Type, true, 0)
+ b.WriteString("\n\n")
+ }
+
+ // Local interface with all methods
+ b.WriteString("type " + pkgname + "Interface interface {\n")
+ for _, m := range midl.Methods {
+ b.WriteString("\t" + m.Name + "(c VarlinkCall")
+ for _, field := range m.In.Fields {
+ b.WriteString(", " + strings.Title(field.Name) + " ")
+ writeType(&b, field.Type, false, 1)
+ }
+ b.WriteString(") error\n")
+ }
+ b.WriteString("}\n\n")
+
+ // Local object with all methods
+ b.WriteString("type VarlinkCall struct{ varlink.Call }\n\n")
+
+ // Reply methods for all varlink errors
+ for _, e := range midl.Errors {
+ b.WriteString("func (c *VarlinkCall) Reply" + e.Name + "(")
+ for i, field := range e.Type.Fields {
+ if i > 0 {
+ b.WriteString(", ")
+ }
+ b.WriteString(sanitizeGoName(field.Name) + " ")
+ writeType(&b, field.Type, false, 1)
+ }
+ b.WriteString(") error {\n")
+ if len(e.Type.Fields) > 0 {
+ b.WriteString("\tvar out ")
+ writeType(&b, e.Type, true, 1)
+ b.WriteString("\n")
+ for _, field := range e.Type.Fields {
+ switch field.Type.Kind {
+ case idl.TypeStruct, idl.TypeArray:
+ b.WriteString("\tout." + strings.Title(field.Name) + " = ")
+ writeType(&b, field.Type, true, 1)
+ b.WriteString("(" + sanitizeGoName(field.Name) + ")\n")
+
+ default:
+ b.WriteString("\tout." + strings.Title(field.Name) + " = " + sanitizeGoName(field.Name) + "\n")
+ }
+ }
+ b.WriteString("\treturn c.ReplyError(\"" + midl.Name + "." + e.Name + "\", &out)\n")
+ } else {
+ b.WriteString("\treturn c.ReplyError(\"" + midl.Name + "." + e.Name + "\", nil)\n")
+ }
+ b.WriteString("}\n\n")
+ }
+
+ // Reply methods for all varlink methods
+ for _, m := range midl.Methods {
+ b.WriteString("func (c *VarlinkCall) Reply" + m.Name + "(")
+ for i, field := range m.Out.Fields {
+ if i > 0 {
+ b.WriteString(", ")
+ }
+ b.WriteString(sanitizeGoName(field.Name) + " ")
+ writeType(&b, field.Type, false, 1)
+ }
+ b.WriteString(") error {\n")
+ if len(m.Out.Fields) > 0 {
+ b.WriteString("\tvar out ")
+ writeType(&b, m.Out, true, 1)
+ b.WriteString("\n")
+ for _, field := range m.Out.Fields {
+ switch field.Type.Kind {
+ case idl.TypeStruct, idl.TypeArray:
+ b.WriteString("\tout." + strings.Title(field.Name) + " = ")
+ writeType(&b, field.Type, true, 1)
+ b.WriteString("(" + sanitizeGoName(field.Name) + ")\n")
+
+ default:
+ b.WriteString("\tout." + strings.Title(field.Name) + " = " + sanitizeGoName(field.Name) + "\n")
+ }
+ }
+ b.WriteString("\treturn c.Reply(&out)\n")
+ } else {
+ b.WriteString("\treturn c.Reply(nil)\n")
+ }
+ b.WriteString("}\n\n")
+ }
+
+ // Dummy methods for all varlink methods
+ for _, m := range midl.Methods {
+ b.WriteString("func (s *VarlinkInterface) " + m.Name + "(c VarlinkCall")
+ for _, field := range m.In.Fields {
+ b.WriteString(", " + sanitizeGoName(field.Name) + " ")
+ writeType(&b, field.Type, false, 1)
+ }
+ b.WriteString(") error {\n" +
+ "\treturn c.ReplyMethodNotImplemented(\"" + m.Name + "\")\n" +
+ "}\n\n")
+ }
+
+ // Method call dispatcher
+ b.WriteString("func (s *VarlinkInterface) VarlinkDispatch(call varlink.Call, methodname string) error {\n" +
+ "\tswitch methodname {\n")
+ for _, m := range midl.Methods {
+ b.WriteString("\tcase \"" + m.Name + "\":\n")
+ if len(m.In.Fields) > 0 {
+ b.WriteString("\t\tvar in ")
+ writeType(&b, m.In, true, 2)
+ b.WriteString("\n")
+ b.WriteString("\t\terr := call.GetParameters(&in)\n" +
+ "\t\tif err != nil {\n" +
+ "\t\t\treturn call.ReplyInvalidParameter(\"parameters\")\n" +
+ "\t\t}\n")
+ b.WriteString("\t\treturn s." + pkgname + "Interface." + m.Name + "(VarlinkCall{call}")
+ if len(m.In.Fields) > 0 {
+ for _, field := range m.In.Fields {
+ switch field.Type.Kind {
+ case idl.TypeStruct, idl.TypeArray:
+ b.WriteString(", ")
+ writeType(&b, field.Type, false, 2)
+ b.WriteString("(in." + strings.Title(field.Name) + ")")
+
+ default:
+ b.WriteString(", in." + strings.Title(field.Name))
+ }
+ }
+ }
+ b.WriteString(")\n")
+ } else {
+ b.WriteString("\t\treturn s." + pkgname + "Interface." + m.Name + "(VarlinkCall{call})\n")
+ }
+ b.WriteString("\n")
+ }
+ b.WriteString("\tdefault:\n" +
+ "\t\treturn call.ReplyMethodNotFound(methodname)\n" +
+ "\t}\n" +
+ "}\n")
+
+ // Varlink interface name
+ b.WriteString("func (s *VarlinkInterface) VarlinkGetName() string {\n" +
+ "\treturn `" + midl.Name + "`\n" + "}\n\n")
+
+ // Varlink interface description
+ b.WriteString("func (s *VarlinkInterface) VarlinkGetDescription() string {\n" +
+ "\treturn `" + midl.Description + "\n`\n}\n\n")
+
+ b.WriteString("type VarlinkInterface struct {\n" +
+ "\t" + pkgname + "Interface\n" +
+ "}\n\n")
+
+ b.WriteString("func VarlinkNew(m " + pkgname + "Interface) *VarlinkInterface {\n" +
+ "\treturn &VarlinkInterface{m}\n" +
+ "}\n")
+
+ return pkgname, b.Bytes(), nil
+}
+
+func generateFile(varlinkFile string) {
+ file, err := ioutil.ReadFile(varlinkFile)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Error reading file '%s': %s\n", varlinkFile, err)
+ os.Exit(1)
+ }
+
+ pkgname, b, err := generateTemplate(string(file))
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Error parsing file '%s': %s\n", varlinkFile, err)
+ os.Exit(1)
+ }
+
+ filename := path.Dir(varlinkFile) + "/" + pkgname + ".go"
+ err = ioutil.WriteFile(filename, b, 0660)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Error writing file '%s': %s\n", filename, err)
+ os.Exit(1)
+ }
+}
+
+func main() {
+ if len(os.Args) != 2 {
+ fmt.Printf("Usage: %s <file>\n", os.Args[0])
+ os.Exit(1)
+ }
+ generateFile(os.Args[1])
+}