diff options
author | Ondrej Fabry <ofabry@cisco.com> | 2020-07-17 10:36:28 +0200 |
---|---|---|
committer | Ondrej Fabry <ofabry@cisco.com> | 2020-07-17 11:43:41 +0200 |
commit | d1f24d37bd447b64e402298bb8eb2479681facf9 (patch) | |
tree | a3fc21ba730a91d8a402c7a5bf9c614e3677c4fc /binapigen/gen_helpers.go | |
parent | 1548c7e12531e3d055567d761c580a1c7ff0ac40 (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.go | 348 |
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() +} |