Change module name to go.fd.io/govpp
[govpp.git] / binapigen / gen_helpers.go
1 //  Copyright (c) 2020 Cisco and/or its affiliates.
2 //
3 //  Licensed under the Apache License, Version 2.0 (the "License");
4 //  you may not use this file except in compliance with the License.
5 //  You may obtain a copy of the License at:
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 //  Unless required by applicable law or agreed to in writing, software
10 //  distributed under the License is distributed on an "AS IS" BASIS,
11 //  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 //  See the License for the specific language governing permissions and
13 //  limitations under the License.
14
15 package binapigen
16
17 func init() {
18         //RegisterPlugin("convert", GenerateConvert)
19 }
20
21 // library dependencies
22 const (
23         fmtPkg     = GoImportPath("fmt")
24         netPkg     = GoImportPath("net")
25         timePkg    = GoImportPath("time")
26         stringsPkg = GoImportPath("strings")
27 )
28
29 func genIPConversion(g *GenFile, structName string, ipv int) {
30         // ParseIPXAddress method
31         g.P("func Parse", structName, "(s string) (", structName, ", error) {")
32         if ipv == 4 {
33                 g.P("   ip := ", netPkg.Ident("ParseIP"), "(s).To4()")
34         } else {
35                 g.P("   ip := ", netPkg.Ident("ParseIP"), "(s).To16()")
36         }
37         g.P("   if ip == nil {")
38         g.P("           return ", structName, "{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP address: %s\", s)")
39         g.P("   }")
40         g.P("   var ipaddr ", structName)
41         if ipv == 4 {
42                 g.P("   copy(ipaddr[:], ip.To4())")
43         } else {
44                 g.P("   copy(ipaddr[:], ip.To16())")
45         }
46         g.P("   return ipaddr, nil")
47         g.P("}")
48         g.P()
49
50         // ToIP method
51         g.P("func (x ", structName, ") ToIP() ", netPkg.Ident("IP"), " {")
52         if ipv == 4 {
53                 g.P("   return ", netPkg.Ident("IP"), "(x[:]).To4()")
54         } else {
55                 g.P("   return ", netPkg.Ident("IP"), "(x[:]).To16()")
56         }
57         g.P("}")
58         g.P()
59
60         // String method
61         g.P("func (x ", structName, ") String() string {")
62         g.P("   return x.ToIP().String()")
63         g.P("}")
64         g.P()
65
66         // MarshalText method
67         g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
68         g.P("   return []byte(x.String()), nil")
69         g.P("}")
70         g.P()
71
72         // UnmarshalText method
73         g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
74         g.P("   ipaddr, err := Parse", structName, "(string(text))")
75         g.P("   if err !=nil {")
76         g.P("           return err")
77         g.P("   }")
78         g.P("   *x = ipaddr")
79         g.P("   return nil")
80         g.P("}")
81         g.P()
82 }
83
84 func genAddressConversion(g *GenFile, structName string) {
85         // ParseAddress method
86         g.P("func Parse", structName, "(s string) (", structName, ", error) {")
87         g.P("   ip := ", netPkg.Ident("ParseIP"), "(s)")
88         g.P("   if ip == nil {")
89         g.P("           return ", structName, "{}, ", fmtPkg.Ident("Errorf"), "(\"invalid address: %s\", s)")
90         g.P("   }")
91         g.P("   return ", structName, "FromIP(ip), nil")
92         g.P("}")
93         g.P()
94
95         // AddressFromIP method
96         g.P("func ", structName, "FromIP(ip ", netPkg.Ident("IP"), ") ", structName, " {")
97         g.P("   var addr ", structName)
98         g.P("   if ip.To4() == nil {")
99         g.P("           addr.Af = ADDRESS_IP6")
100         g.P("           var ip6 IP6Address")
101         g.P("           copy(ip6[:], ip.To16())")
102         g.P("           addr.Un.SetIP6(ip6)")
103         g.P("   } else {")
104         g.P("           addr.Af = ADDRESS_IP4")
105         g.P("           var ip4 IP4Address")
106         g.P("           copy(ip4[:], ip.To4())")
107         g.P("           addr.Un.SetIP4(ip4)")
108         g.P("   }")
109         g.P("   return addr")
110         g.P("}")
111         g.P()
112
113         // ToIP method
114         g.P("func (x ", structName, ") ToIP() ", netPkg.Ident("IP"), " {")
115         g.P("   if x.Af == ADDRESS_IP6 {")
116         g.P("           ip6 := x.Un.GetIP6()")
117         g.P("           return ", netPkg.Ident("IP"), "(ip6[:]).To16()")
118         g.P("   } else {")
119         g.P("           ip4 := x.Un.GetIP4()")
120         g.P("           return ", netPkg.Ident("IP"), "(ip4[:]).To4()")
121         g.P("   }")
122         g.P("}")
123         g.P()
124
125         // String method
126         g.P("func (x ", structName, ") String() string {")
127         g.P("   return x.ToIP().String()")
128         g.P("}")
129         g.P()
130
131         // MarshalText method
132         g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
133         g.P("   return []byte(x.String()), nil")
134         g.P("}")
135         g.P()
136
137         // UnmarshalText method
138         g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
139         g.P("   addr, err := Parse", structName, "(string(text))")
140         g.P("   if err != nil {")
141         g.P("           return err")
142         g.P("   }")
143         g.P("   *x = addr")
144         g.P("   return nil")
145         g.P("}")
146         g.P()
147 }
148
149 func genIPPrefixConversion(g *GenFile, structName string, ipv int) {
150         // ParsePrefix method
151         g.P("func Parse", structName, "(s string) (prefix ", structName, ", err error) {")
152         g.P("   hasPrefix := ", stringsPkg.Ident("Contains"), "(s, \"/\")")
153         g.P("   if hasPrefix {")
154         g.P("           ip, network, err := ", netPkg.Ident("ParseCIDR"), "(s)")
155         g.P("           if err != nil {")
156         g.P("                   return ", structName, "{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP %s: %s\", s, err)")
157         g.P("           }")
158         g.P("           maskSize, _ := network.Mask.Size()")
159         g.P("           prefix.Len = byte(maskSize)")
160         if ipv == 4 {
161                 g.P("           prefix.Address, err = ParseIP4Address(ip.String())")
162         } else {
163                 g.P("           prefix.Address, err = ParseIP6Address(ip.String())")
164         }
165         g.P("           if err != nil {")
166         g.P("                   return ", structName, "{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP %s: %s\", s, err)")
167         g.P("           }")
168         g.P("   } else {")
169         g.P("           ip :=  ", netPkg.Ident("ParseIP"), "(s)")
170         g.P("           defaultMaskSize, _ := ", netPkg.Ident("CIDRMask"), "(32, 32).Size()")
171         g.P("           if ip.To4() == nil {")
172         g.P("                   defaultMaskSize, _ =", netPkg.Ident("CIDRMask"), "(128, 128).Size()")
173         g.P("           }")
174         g.P("           prefix.Len = byte(defaultMaskSize)")
175         if ipv == 4 {
176                 g.P("           prefix.Address, err = ParseIP4Address(ip.String())")
177         } else {
178                 g.P("           prefix.Address, err = ParseIP6Address(ip.String())")
179         }
180         g.P("           if err != nil {")
181         g.P("                   return ", structName, "{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP %s: %s\", s, err)")
182         g.P("           }")
183         g.P("   }")
184         g.P("   return prefix, nil")
185         g.P("}")
186         g.P()
187
188         // ToIPNet method
189         g.P("func (x ", structName, ") ToIPNet() *", netPkg.Ident("IPNet"), " {")
190         if ipv == 4 {
191                 g.P("   mask := ", netPkg.Ident("CIDRMask"), "(int(x.Len), 32)")
192         } else {
193                 g.P("   mask := ", netPkg.Ident("CIDRMask"), "(int(x.Len), 128)")
194         }
195         g.P("   ipnet := &", netPkg.Ident("IPNet"), "{IP: x.Address.ToIP(), Mask: mask}")
196         g.P("   return ipnet")
197         g.P("}")
198         g.P()
199
200         // String method
201         g.P("func (x ", structName, ") String() string {")
202         g.P("   ip := x.Address.String()")
203         g.P("   return ip + \"/\" + ", strconvPkg.Ident("Itoa"), "(int(x.Len))")
204         g.P("}")
205         g.P()
206
207         // MarshalText method
208         g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
209         g.P("   return []byte(x.String()), nil")
210         g.P("}")
211         g.P()
212
213         // UnmarshalText method
214         g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
215         g.P("   prefix, err := Parse", structName, "(string(text))")
216         g.P("   if err != nil {")
217         g.P("           return err")
218         g.P("   }")
219         g.P("   *x = prefix")
220         g.P("   return nil")
221         g.P("}")
222         g.P()
223 }
224
225 func genPrefixConversion(g *GenFile, structName string) {
226         // ParsePrefix method
227         g.P("func Parse", structName, "(ip string) (prefix ", structName, ", err error) {")
228         g.P("   hasPrefix := ", stringsPkg.Ident("Contains"), "(ip, \"/\")")
229         g.P("   if hasPrefix {")
230         g.P("           netIP, network, err := ", netPkg.Ident("ParseCIDR"), "(ip)")
231         g.P("           if err != nil {")
232         g.P("                   return Prefix{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP %s: %s\", ip, err)")
233         g.P("           }")
234         g.P("           maskSize, _ := network.Mask.Size()")
235         g.P("           prefix.Len = byte(maskSize)")
236         g.P("           prefix.Address, err = ParseAddress(netIP.String())")
237         g.P("           if err != nil {")
238         g.P("                   return Prefix{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP %s: %s\", ip, err)")
239         g.P("           }")
240         g.P("   } else {")
241         g.P("           netIP :=  ", netPkg.Ident("ParseIP"), "(ip)")
242         g.P("           defaultMaskSize, _ := ", netPkg.Ident("CIDRMask"), "(32, 32).Size()")
243         g.P("           if netIP.To4() == nil {")
244         g.P("                   defaultMaskSize, _ =", netPkg.Ident("CIDRMask"), "(128, 128).Size()")
245         g.P("           }")
246         g.P("           prefix.Len = byte(defaultMaskSize)")
247         g.P("           prefix.Address, err = ParseAddress(netIP.String())")
248         g.P("           if err != nil {")
249         g.P("                   return Prefix{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP %s: %s\", ip, err)")
250         g.P("           }")
251         g.P("   }")
252         g.P("   return prefix, nil")
253         g.P("}")
254         g.P()
255
256         // ToIPNet method
257         g.P("func (x ", structName, ") ToIPNet() *", netPkg.Ident("IPNet"), " {")
258         g.P("   var mask ", netPkg.Ident("IPMask"))
259         g.P("   if x.Address.Af == ADDRESS_IP4 {")
260         g.P("   mask = ", netPkg.Ident("CIDRMask"), "(int(x.Len), 32)")
261         g.P("   } else {")
262         g.P("   mask = ", netPkg.Ident("CIDRMask"), "(int(x.Len), 128)")
263         g.P("   }")
264         g.P("   ipnet := &", netPkg.Ident("IPNet"), "{IP: x.Address.ToIP(), Mask: mask}")
265         g.P("   return ipnet")
266         g.P("}")
267         g.P()
268
269         // String method
270         g.P("func (x ", structName, ") String() string {")
271         g.P("   ip := x.Address.String()")
272         g.P("   return ip + \"/\" + ", strconvPkg.Ident("Itoa"), "(int(x.Len))")
273         g.P("}")
274         g.P()
275
276         // MarshalText method
277         g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
278         g.P("   return []byte(x.String()), nil")
279         g.P("}")
280         g.P()
281
282         // UnmarshalText method
283         g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
284         g.P("   prefix, err := Parse", structName, "(string(text))")
285         g.P("   if err !=nil {")
286         g.P("           return err")
287         g.P("   }")
288         g.P("   *x = prefix")
289         g.P("   return nil")
290         g.P("}")
291         g.P()
292 }
293
294 func genAddressWithPrefixConversion(g *GenFile, structName string) {
295         // ParseAddressWithPrefix method
296         g.P("func Parse", structName, "(s string) (", structName, ", error) {")
297         g.P("   prefix, err := ParsePrefix(s)")
298         g.P("   if err != nil {")
299         g.P("           return ", structName, "{}, err")
300         g.P("   }")
301         g.P("   return ", structName, "(prefix), nil")
302         g.P("}")
303         g.P()
304
305         // String method
306         g.P("func (x ", structName, ") String() string {")
307         g.P("   return Prefix(x).String()")
308         g.P("}")
309         g.P()
310
311         // MarshalText method
312         g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
313         g.P("   return []byte(x.String()), nil")
314         g.P("}")
315         g.P()
316
317         // UnmarshalText method
318         g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
319         g.P("   prefix, err := Parse", structName, "(string(text))")
320         g.P("   if err != nil {")
321         g.P("           return err")
322         g.P("   }")
323         g.P("   *x = prefix")
324         g.P("   return nil")
325         g.P("}")
326         g.P()
327 }
328
329 func genMacAddressConversion(g *GenFile, structName string) {
330         // ParseMAC method
331         g.P("func Parse", structName, "(s string) (", structName, ", error) {")
332         g.P("   var macaddr ", structName)
333         g.P("   mac, err := ", netPkg.Ident("ParseMAC"), "(s)")
334         g.P("   if err != nil {")
335         g.P("           return macaddr, err")
336         g.P("   }")
337         g.P("   copy(macaddr[:], mac[:])")
338         g.P("   return macaddr, nil")
339         g.P("}")
340         g.P()
341
342         // ToMAC method
343         g.P("func (x ", structName, ") ToMAC() ", netPkg.Ident("HardwareAddr"), " {")
344         g.P("   return ", netPkg.Ident("HardwareAddr"), "(x[:])")
345         g.P("}")
346         g.P()
347
348         // String method
349         g.P("func (x ", structName, ") String() string {")
350         g.P("   return x.ToMAC().String()")
351         g.P("}")
352         g.P()
353
354         // MarshalText method
355         g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
356         g.P("   return []byte(x.String()), nil")
357         g.P("}")
358         g.P()
359
360         // UnmarshalText method
361         g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
362         g.P("   mac, err := Parse", structName, "(string(text))")
363         g.P("   if err != nil {")
364         g.P("           return err")
365         g.P("   }")
366         g.P("   *x = mac")
367         g.P("   return nil")
368         g.P("}")
369         g.P()
370 }
371
372 func genTimestampConversion(g *GenFile, structName string) {
373         // NewTimestamp method
374         g.P("func New", structName, "(t ", timePkg.Ident("Time"), ") ", structName, " {")
375         g.P("   sec := int64(t.Unix())")
376         g.P("   nsec := int32(t.Nanosecond())")
377         g.P("   ns := float64(sec) + float64(nsec / 1e9)")
378         g.P("   return ", structName, "(ns)")
379         g.P("}")
380         g.P()
381
382         // ToTime method
383         g.P("func (x ", structName, ") ToTime() ", timePkg.Ident("Time"), " {")
384         g.P("   ns := int64(x * 1e9)")
385         g.P("   sec := ns / 1e9")
386         g.P("   nsec := ns % 1e9")
387         g.P("   return ", timePkg.Ident("Unix"), "(sec, nsec)")
388         g.P("}")
389         g.P()
390
391         // String method
392         g.P("func (x ", structName, ") String() string {")
393         g.P("   return x.ToTime().String()")
394         g.P("}")
395         g.P()
396
397         // MarshalText method
398         g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
399         g.P("   return []byte(x.ToTime().Format(", timePkg.Ident("RFC3339Nano"), ")), nil")
400         g.P("}")
401         g.P()
402
403         // UnmarshalText method
404         g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
405         g.P("   t, err := ", timePkg.Ident("Parse"), "(", timePkg.Ident("RFC3339Nano"), ", string(text))")
406         g.P("   if err != nil {")
407         g.P("           return err")
408         g.P("   }")
409         g.P("   *x = New", structName, "(t)")
410         g.P("   return nil")
411         g.P("}")
412         g.P()
413 }