summaryrefslogtreecommitdiffstats
path: root/binapigen/gen_helpers.go
diff options
context:
space:
mode:
authorOndrej Fabry <ofabry@cisco.com>2020-07-17 10:36:28 +0200
committerOndrej Fabry <ofabry@cisco.com>2020-07-17 11:43:41 +0200
commitd1f24d37bd447b64e402298bb8eb2479681facf9 (patch)
treea3fc21ba730a91d8a402c7a5bf9c614e3677c4fc /binapigen/gen_helpers.go
parent1548c7e12531e3d055567d761c580a1c7ff0ac40 (diff)
Improve binapi generator
- simplified Size/Marshal/Unmarshal methods - replace struc in unions with custom marshal/unmarshal - fix imports in generated files - fix mock adapter - generate rpc service using low-level stream API (dumps generate control ping or stream msg..) - move examples/binapi to binapi and generate all API for latest release - add binapigen.Plugin for developing custom generator plugins - optionally generate HTTP handlers (REST API) for RPC services - add govpp program for browsing VPP API Change-Id: I092e9ed2b0c17972b3476463c3d4b14dd76ed42b Signed-off-by: Ondrej Fabry <ofabry@cisco.com>
Diffstat (limited to 'binapigen/gen_helpers.go')
-rw-r--r--binapigen/gen_helpers.go348
1 files changed, 348 insertions, 0 deletions
diff --git a/binapigen/gen_helpers.go b/binapigen/gen_helpers.go
new file mode 100644
index 0000000..a22f1c6
--- /dev/null
+++ b/binapigen/gen_helpers.go
@@ -0,0 +1,348 @@
+// Copyright (c) 2020 Cisco and/or its affiliates.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package binapigen
+
+func init() {
+ //RegisterPlugin("convert", GenerateConvert)
+}
+
+// library dependencies
+const (
+ fmtPkg = GoImportPath("fmt")
+ netPkg = GoImportPath("net")
+ stringsPkg = GoImportPath("strings")
+)
+
+func generateIPConversion(g *GenFile, structName string, ipv int) {
+ // ParseIPXAddress method
+ g.P("func Parse", structName, "(s string) (", structName, ", error) {")
+ if ipv == 4 {
+ g.P(" ip := ", netPkg.Ident("ParseIP"), "(s).To4()")
+ } else {
+ g.P(" ip := ", netPkg.Ident("ParseIP"), "(s).To16()")
+ }
+ g.P(" if ip == nil {")
+ g.P(" return ", structName, "{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP address: %s\", s)")
+ g.P(" }")
+ g.P(" var ipaddr ", structName)
+ if ipv == 4 {
+ g.P(" copy(ipaddr[:], ip.To4())")
+ } else {
+ g.P(" copy(ipaddr[:], ip.To16())")
+ }
+ g.P(" return ipaddr, nil")
+ g.P("}")
+ g.P()
+
+ // ToIP method
+ g.P("func (x ", structName, ") ToIP() ", netPkg.Ident("IP"), " {")
+ if ipv == 4 {
+ g.P(" return ", netPkg.Ident("IP"), "(x[:]).To4()")
+ } else {
+ g.P(" return ", netPkg.Ident("IP"), "(x[:]).To16()")
+ }
+ g.P("}")
+
+ // String method
+ g.P("func (x ", structName, ") String() string {")
+ g.P(" return x.ToIP().String()")
+ g.P("}")
+
+ // MarshalText method
+ g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
+ g.P(" return []byte(x.String()), nil")
+ g.P("}")
+
+ // UnmarshalText method
+ g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
+ g.P(" ipaddr, err := Parse", structName, "(string(text))")
+ g.P(" if err !=nil {")
+ g.P(" return err")
+ g.P(" }")
+ g.P(" *x = ipaddr")
+ g.P(" return nil")
+ g.P("}")
+ g.P()
+}
+
+func generateAddressConversion(g *GenFile, structName string) {
+ // ParseAddress method
+ g.P("func Parse", structName, "(s string) (", structName, ", error) {")
+ g.P(" ip := ", netPkg.Ident("ParseIP"), "(s)")
+ g.P(" if ip == nil {")
+ g.P(" return ", structName, "{}, ", fmtPkg.Ident("Errorf"), "(\"invalid address: %s\", s)")
+ g.P(" }")
+ g.P(" var addr ", structName)
+ g.P(" if ip.To4() == nil {")
+ g.P(" addr.Af = ADDRESS_IP6")
+ g.P(" var ip6 IP6Address")
+ g.P(" copy(ip6[:], ip.To16())")
+ g.P(" addr.Un.SetIP6(ip6)")
+ g.P(" } else {")
+ g.P(" addr.Af = ADDRESS_IP4")
+ g.P(" var ip4 IP4Address")
+ g.P(" copy(ip4[:], ip.To4())")
+ g.P(" addr.Un.SetIP4(ip4)")
+ g.P(" }")
+ g.P(" return addr, nil")
+ g.P("}")
+
+ // ToIP method
+ g.P("func (x ", structName, ") ToIP() ", netPkg.Ident("IP"), " {")
+ g.P(" if x.Af == ADDRESS_IP6 {")
+ g.P(" ip6 := x.Un.GetIP6()")
+ g.P(" return ", netPkg.Ident("IP"), "(ip6[:]).To16()")
+ g.P(" } else {")
+ g.P(" ip4 := x.Un.GetIP4()")
+ g.P(" return ", netPkg.Ident("IP"), "(ip4[:]).To4()")
+ g.P(" }")
+ g.P("}")
+
+ // String method
+ g.P("func (x ", structName, ") String() string {")
+ g.P(" return x.ToIP().String()")
+ g.P("}")
+
+ // MarshalText method
+ g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
+ g.P(" return []byte(x.String()), nil")
+ g.P("}")
+
+ // UnmarshalText method
+ g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
+ g.P(" addr, err := Parse", structName, "(string(text))")
+ g.P(" if err != nil {")
+ g.P(" return err")
+ g.P(" }")
+ g.P(" *x = addr")
+ g.P(" return nil")
+ g.P("}")
+ g.P()
+}
+
+func generateIPPrefixConversion(g *GenFile, structName string, ipv int) {
+ // ParsePrefix method
+ g.P("func Parse", structName, "(s string) (prefix ", structName, ", err error) {")
+ g.P(" hasPrefix := ", stringsPkg.Ident("Contains"), "(s, \"/\")")
+ g.P(" if hasPrefix {")
+ g.P(" ip, network, err := ", netPkg.Ident("ParseCIDR"), "(s)")
+ g.P(" if err != nil {")
+ g.P(" return ", structName, "{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP %s: %s\", s, err)")
+ g.P(" }")
+ g.P(" maskSize, _ := network.Mask.Size()")
+ g.P(" prefix.Len = byte(maskSize)")
+ if ipv == 4 {
+ g.P(" prefix.Address, err = ParseIP4Address(ip.String())")
+ } else {
+ g.P(" prefix.Address, err = ParseIP6Address(ip.String())")
+ }
+ g.P(" if err != nil {")
+ g.P(" return ", structName, "{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP %s: %s\", s, err)")
+ g.P(" }")
+ g.P(" } else {")
+ g.P(" ip := ", netPkg.Ident("ParseIP"), "(s)")
+ g.P(" defaultMaskSize, _ := ", netPkg.Ident("CIDRMask"), "(32, 32).Size()")
+ g.P(" if ip.To4() == nil {")
+ g.P(" defaultMaskSize, _ =", netPkg.Ident("CIDRMask"), "(128, 128).Size()")
+ g.P(" }")
+ g.P(" prefix.Len = byte(defaultMaskSize)")
+ if ipv == 4 {
+ g.P(" prefix.Address, err = ParseIP4Address(ip.String())")
+ } else {
+ g.P(" prefix.Address, err = ParseIP6Address(ip.String())")
+ }
+ g.P(" if err != nil {")
+ g.P(" return ", structName, "{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP %s: %s\", s, err)")
+ g.P(" }")
+ g.P(" }")
+ g.P(" return prefix, nil")
+ g.P("}")
+
+ // ToIPNet method
+ g.P("func (x ", structName, ") ToIPNet() *", netPkg.Ident("IPNet"), " {")
+ if ipv == 4 {
+ g.P(" mask := ", netPkg.Ident("CIDRMask"), "(int(x.Len), 32)")
+ } else {
+ g.P(" mask := ", netPkg.Ident("CIDRMask"), "(int(x.Len), 128)")
+ }
+ g.P(" ipnet := &", netPkg.Ident("IPNet"), "{IP: x.Address.ToIP(), Mask: mask}")
+ g.P(" return ipnet")
+ g.P("}")
+
+ // String method
+ g.P("func (x ", structName, ") String() string {")
+ g.P(" ip := x.Address.String()")
+ g.P(" return ip + \"/\" + ", strconvPkg.Ident("Itoa"), "(int(x.Len))")
+ /*if ipv == 4 {
+ g.P(" mask := ", netPkg.Ident("CIDRMask"), "(int(x.Len), 32)")
+ } else {
+ g.P(" mask := ", netPkg.Ident("CIDRMask"), "(int(x.Len), 128)")
+ }
+ g.P(" ipnet := &", netPkg.Ident("IPNet"), "{IP: x.Address.ToIP(), Mask: mask}")
+ g.P(" return ipnet.String()")*/
+ g.P("}")
+
+ // MarshalText method
+ g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
+ g.P(" return []byte(x.String()), nil")
+ g.P("}")
+
+ // UnmarshalText method
+ g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
+ g.P(" prefix, err := Parse", structName, "(string(text))")
+ g.P(" if err != nil {")
+ g.P(" return err")
+ g.P(" }")
+ g.P(" *x = prefix")
+ g.P(" return nil")
+ g.P("}")
+ g.P()
+}
+
+func generatePrefixConversion(g *GenFile, structName string) {
+ // ParsePrefix method
+ g.P("func Parse", structName, "(ip string) (prefix ", structName, ", err error) {")
+ g.P(" hasPrefix := ", stringsPkg.Ident("Contains"), "(ip, \"/\")")
+ g.P(" if hasPrefix {")
+ g.P(" netIP, network, err := ", netPkg.Ident("ParseCIDR"), "(ip)")
+ g.P(" if err != nil {")
+ g.P(" return Prefix{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP %s: %s\", ip, err)")
+ g.P(" }")
+ g.P(" maskSize, _ := network.Mask.Size()")
+ g.P(" prefix.Len = byte(maskSize)")
+ g.P(" prefix.Address, err = ParseAddress(netIP.String())")
+ g.P(" if err != nil {")
+ g.P(" return Prefix{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP %s: %s\", ip, err)")
+ g.P(" }")
+ g.P(" } else {")
+ g.P(" netIP := ", netPkg.Ident("ParseIP"), "(ip)")
+ g.P(" defaultMaskSize, _ := ", netPkg.Ident("CIDRMask"), "(32, 32).Size()")
+ g.P(" if netIP.To4() == nil {")
+ g.P(" defaultMaskSize, _ =", netPkg.Ident("CIDRMask"), "(128, 128).Size()")
+ g.P(" }")
+ g.P(" prefix.Len = byte(defaultMaskSize)")
+ g.P(" prefix.Address, err = ParseAddress(netIP.String())")
+ g.P(" if err != nil {")
+ g.P(" return Prefix{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP %s: %s\", ip, err)")
+ g.P(" }")
+ g.P(" }")
+ g.P(" return prefix, nil")
+ g.P("}")
+
+ // ToIPNet method
+ g.P("func (x ", structName, ") ToIPNet() *", netPkg.Ident("IPNet"), " {")
+ g.P(" var mask ", netPkg.Ident("IPMask"))
+ g.P(" if x.Address.Af == ADDRESS_IP4 {")
+ g.P(" mask = ", netPkg.Ident("CIDRMask"), "(int(x.Len), 32)")
+ g.P(" } else {")
+ g.P(" mask = ", netPkg.Ident("CIDRMask"), "(int(x.Len), 128)")
+ g.P(" }")
+ g.P(" ipnet := &", netPkg.Ident("IPNet"), "{IP: x.Address.ToIP(), Mask: mask}")
+ g.P(" return ipnet")
+ g.P("}")
+
+ // String method
+ g.P("func (x ", structName, ") String() string {")
+ g.P(" ip := x.Address.String()")
+ g.P(" return ip + \"/\" + ", strconvPkg.Ident("Itoa"), "(int(x.Len))")
+ g.P("}")
+
+ // MarshalText method
+ g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
+ g.P(" return []byte(x.String()), nil")
+ g.P("}")
+
+ // UnmarshalText method
+ g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
+ g.P(" prefix, err := Parse", structName, "(string(text))")
+ g.P(" if err !=nil {")
+ g.P(" return err")
+ g.P(" }")
+ g.P(" *x = prefix")
+ g.P(" return nil")
+ g.P("}")
+ g.P()
+}
+
+func generateAddressWithPrefixConversion(g *GenFile, structName string) {
+ // ParseAddressWithPrefix method
+ g.P("func Parse", structName, "(s string) (", structName, ", error) {")
+ g.P(" prefix, err := ParsePrefix(s)")
+ g.P(" if err != nil {")
+ g.P(" return ", structName, "{}, err")
+ g.P(" }")
+ g.P(" return ", structName, "(prefix), nil")
+ g.P("}")
+
+ // String method
+ g.P("func (x ", structName, ") String() string {")
+ g.P(" return Prefix(x).String()")
+ g.P("}")
+
+ // MarshalText method
+ g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
+ g.P(" return []byte(x.String()), nil")
+ g.P("}")
+
+ // UnmarshalText method
+ g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
+ g.P(" prefix, err := Parse", structName, "(string(text))")
+ g.P(" if err != nil {")
+ g.P(" return err")
+ g.P(" }")
+ g.P(" *x = prefix")
+ g.P(" return nil")
+ g.P("}")
+ g.P()
+}
+
+func generateMacAddressConversion(g *GenFile, structName string) {
+ // ParseMAC method
+ g.P("func Parse", structName, "(s string) (", structName, ", error) {")
+ g.P(" var macaddr ", structName)
+ g.P(" mac, err := ", netPkg.Ident("ParseMAC"), "(s)")
+ g.P(" if err != nil {")
+ g.P(" return macaddr, err")
+ g.P(" }")
+ g.P(" copy(macaddr[:], mac[:])")
+ g.P(" return macaddr, nil")
+ g.P("}")
+
+ // ToMAC method
+ g.P("func (x ", structName, ") ToMAC() ", netPkg.Ident("HardwareAddr"), " {")
+ g.P(" return ", netPkg.Ident("HardwareAddr"), "(x[:])")
+ g.P("}")
+
+ // String method
+ g.P("func (x ", structName, ") String() string {")
+ g.P(" return x.ToMAC().String()")
+ g.P("}")
+
+ // MarshalText method
+ g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
+ g.P(" return []byte(x.String()), nil")
+ g.P("}")
+
+ // UnmarshalText method
+ g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
+ g.P(" mac, err := Parse", structName, "(string(text))")
+ g.P(" if err != nil {")
+ g.P(" return err")
+ g.P(" }")
+ g.P(" *x = mac")
+ g.P(" return nil")
+ g.P("}")
+ g.P()
+}