Recognize stat_dir_type_empty
[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
59         // String method
60         g.P("func (x ", structName, ") String() string {")
61         g.P("   return x.ToIP().String()")
62         g.P("}")
63
64         // MarshalText method
65         g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
66         g.P("   return []byte(x.String()), nil")
67         g.P("}")
68
69         // UnmarshalText method
70         g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
71         g.P("   ipaddr, err := Parse", structName, "(string(text))")
72         g.P("   if err !=nil {")
73         g.P("           return err")
74         g.P("   }")
75         g.P("   *x = ipaddr")
76         g.P("   return nil")
77         g.P("}")
78         g.P()
79 }
80
81 func genAddressConversion(g *GenFile, structName string) {
82         // ParseAddress method
83         g.P("func Parse", structName, "(s string) (", structName, ", error) {")
84         g.P("   ip := ", netPkg.Ident("ParseIP"), "(s)")
85         g.P("   if ip == nil {")
86         g.P("           return ", structName, "{}, ", fmtPkg.Ident("Errorf"), "(\"invalid address: %s\", s)")
87         g.P("   }")
88         g.P("   var addr ", structName)
89         g.P("   if ip.To4() == nil {")
90         g.P("           addr.Af = ADDRESS_IP6")
91         g.P("           var ip6 IP6Address")
92         g.P("           copy(ip6[:], ip.To16())")
93         g.P("           addr.Un.SetIP6(ip6)")
94         g.P("   } else {")
95         g.P("           addr.Af = ADDRESS_IP4")
96         g.P("           var ip4 IP4Address")
97         g.P("           copy(ip4[:], ip.To4())")
98         g.P("           addr.Un.SetIP4(ip4)")
99         g.P("   }")
100         g.P("   return addr, nil")
101         g.P("}")
102
103         // ToIP method
104         g.P("func (x ", structName, ") ToIP() ", netPkg.Ident("IP"), " {")
105         g.P("   if x.Af == ADDRESS_IP6 {")
106         g.P("           ip6 := x.Un.GetIP6()")
107         g.P("           return ", netPkg.Ident("IP"), "(ip6[:]).To16()")
108         g.P("   } else {")
109         g.P("           ip4 := x.Un.GetIP4()")
110         g.P("           return ", netPkg.Ident("IP"), "(ip4[:]).To4()")
111         g.P("   }")
112         g.P("}")
113
114         // String method
115         g.P("func (x ", structName, ") String() string {")
116         g.P("   return x.ToIP().String()")
117         g.P("}")
118
119         // MarshalText method
120         g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
121         g.P("   return []byte(x.String()), nil")
122         g.P("}")
123
124         // UnmarshalText method
125         g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
126         g.P("   addr, err := Parse", structName, "(string(text))")
127         g.P("   if err != nil {")
128         g.P("           return err")
129         g.P("   }")
130         g.P("   *x = addr")
131         g.P("   return nil")
132         g.P("}")
133         g.P()
134 }
135
136 func genIPPrefixConversion(g *GenFile, structName string, ipv int) {
137         // ParsePrefix method
138         g.P("func Parse", structName, "(s string) (prefix ", structName, ", err error) {")
139         g.P("   hasPrefix := ", stringsPkg.Ident("Contains"), "(s, \"/\")")
140         g.P("   if hasPrefix {")
141         g.P("           ip, network, err := ", netPkg.Ident("ParseCIDR"), "(s)")
142         g.P("           if err != nil {")
143         g.P("                   return ", structName, "{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP %s: %s\", s, err)")
144         g.P("           }")
145         g.P("           maskSize, _ := network.Mask.Size()")
146         g.P("           prefix.Len = byte(maskSize)")
147         if ipv == 4 {
148                 g.P("           prefix.Address, err = ParseIP4Address(ip.String())")
149         } else {
150                 g.P("           prefix.Address, err = ParseIP6Address(ip.String())")
151         }
152         g.P("           if err != nil {")
153         g.P("                   return ", structName, "{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP %s: %s\", s, err)")
154         g.P("           }")
155         g.P("   } else {")
156         g.P("           ip :=  ", netPkg.Ident("ParseIP"), "(s)")
157         g.P("           defaultMaskSize, _ := ", netPkg.Ident("CIDRMask"), "(32, 32).Size()")
158         g.P("           if ip.To4() == nil {")
159         g.P("                   defaultMaskSize, _ =", netPkg.Ident("CIDRMask"), "(128, 128).Size()")
160         g.P("           }")
161         g.P("           prefix.Len = byte(defaultMaskSize)")
162         if ipv == 4 {
163                 g.P("           prefix.Address, err = ParseIP4Address(ip.String())")
164         } else {
165                 g.P("           prefix.Address, err = ParseIP6Address(ip.String())")
166         }
167         g.P("           if err != nil {")
168         g.P("                   return ", structName, "{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP %s: %s\", s, err)")
169         g.P("           }")
170         g.P("   }")
171         g.P("   return prefix, nil")
172         g.P("}")
173
174         // ToIPNet method
175         g.P("func (x ", structName, ") ToIPNet() *", netPkg.Ident("IPNet"), " {")
176         if ipv == 4 {
177                 g.P("   mask := ", netPkg.Ident("CIDRMask"), "(int(x.Len), 32)")
178         } else {
179                 g.P("   mask := ", netPkg.Ident("CIDRMask"), "(int(x.Len), 128)")
180         }
181         g.P("   ipnet := &", netPkg.Ident("IPNet"), "{IP: x.Address.ToIP(), Mask: mask}")
182         g.P("   return ipnet")
183         g.P("}")
184
185         // String method
186         g.P("func (x ", structName, ") String() string {")
187         g.P("   ip := x.Address.String()")
188         g.P("   return ip + \"/\" + ", strconvPkg.Ident("Itoa"), "(int(x.Len))")
189         g.P("}")
190
191         // MarshalText method
192         g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
193         g.P("   return []byte(x.String()), nil")
194         g.P("}")
195
196         // UnmarshalText method
197         g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
198         g.P("   prefix, err := Parse", structName, "(string(text))")
199         g.P("   if err != nil {")
200         g.P("           return err")
201         g.P("   }")
202         g.P("   *x = prefix")
203         g.P("   return nil")
204         g.P("}")
205         g.P()
206 }
207
208 func genPrefixConversion(g *GenFile, structName string) {
209         // ParsePrefix method
210         g.P("func Parse", structName, "(ip string) (prefix ", structName, ", err error) {")
211         g.P("   hasPrefix := ", stringsPkg.Ident("Contains"), "(ip, \"/\")")
212         g.P("   if hasPrefix {")
213         g.P("           netIP, network, err := ", netPkg.Ident("ParseCIDR"), "(ip)")
214         g.P("           if err != nil {")
215         g.P("                   return Prefix{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP %s: %s\", ip, err)")
216         g.P("           }")
217         g.P("           maskSize, _ := network.Mask.Size()")
218         g.P("           prefix.Len = byte(maskSize)")
219         g.P("           prefix.Address, err = ParseAddress(netIP.String())")
220         g.P("           if err != nil {")
221         g.P("                   return Prefix{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP %s: %s\", ip, err)")
222         g.P("           }")
223         g.P("   } else {")
224         g.P("           netIP :=  ", netPkg.Ident("ParseIP"), "(ip)")
225         g.P("           defaultMaskSize, _ := ", netPkg.Ident("CIDRMask"), "(32, 32).Size()")
226         g.P("           if netIP.To4() == nil {")
227         g.P("                   defaultMaskSize, _ =", netPkg.Ident("CIDRMask"), "(128, 128).Size()")
228         g.P("           }")
229         g.P("           prefix.Len = byte(defaultMaskSize)")
230         g.P("           prefix.Address, err = ParseAddress(netIP.String())")
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("   }")
235         g.P("   return prefix, nil")
236         g.P("}")
237
238         // ToIPNet method
239         g.P("func (x ", structName, ") ToIPNet() *", netPkg.Ident("IPNet"), " {")
240         g.P("   var mask ", netPkg.Ident("IPMask"))
241         g.P("   if x.Address.Af == ADDRESS_IP4 {")
242         g.P("   mask = ", netPkg.Ident("CIDRMask"), "(int(x.Len), 32)")
243         g.P("   } else {")
244         g.P("   mask = ", netPkg.Ident("CIDRMask"), "(int(x.Len), 128)")
245         g.P("   }")
246         g.P("   ipnet := &", netPkg.Ident("IPNet"), "{IP: x.Address.ToIP(), Mask: mask}")
247         g.P("   return ipnet")
248         g.P("}")
249
250         // String method
251         g.P("func (x ", structName, ") String() string {")
252         g.P("   ip := x.Address.String()")
253         g.P("   return ip + \"/\" + ", strconvPkg.Ident("Itoa"), "(int(x.Len))")
254         g.P("}")
255
256         // MarshalText method
257         g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
258         g.P("   return []byte(x.String()), nil")
259         g.P("}")
260
261         // UnmarshalText method
262         g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
263         g.P("   prefix, err := Parse", structName, "(string(text))")
264         g.P("   if err !=nil {")
265         g.P("           return err")
266         g.P("   }")
267         g.P("   *x = prefix")
268         g.P("   return nil")
269         g.P("}")
270         g.P()
271 }
272
273 func genAddressWithPrefixConversion(g *GenFile, structName string) {
274         // ParseAddressWithPrefix method
275         g.P("func Parse", structName, "(s string) (", structName, ", error) {")
276         g.P("   prefix, err := ParsePrefix(s)")
277         g.P("   if err != nil {")
278         g.P("           return ", structName, "{}, err")
279         g.P("   }")
280         g.P("   return ", structName, "(prefix), nil")
281         g.P("}")
282
283         // String method
284         g.P("func (x ", structName, ") String() string {")
285         g.P("   return Prefix(x).String()")
286         g.P("}")
287
288         // MarshalText method
289         g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
290         g.P("   return []byte(x.String()), nil")
291         g.P("}")
292
293         // UnmarshalText method
294         g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
295         g.P("   prefix, err := Parse", structName, "(string(text))")
296         g.P("   if err != nil {")
297         g.P("           return err")
298         g.P("   }")
299         g.P("   *x = prefix")
300         g.P("   return nil")
301         g.P("}")
302         g.P()
303 }
304
305 func genMacAddressConversion(g *GenFile, structName string) {
306         // ParseMAC method
307         g.P("func Parse", structName, "(s string) (", structName, ", error) {")
308         g.P("   var macaddr ", structName)
309         g.P("   mac, err := ", netPkg.Ident("ParseMAC"), "(s)")
310         g.P("   if err != nil {")
311         g.P("           return macaddr, err")
312         g.P("   }")
313         g.P("   copy(macaddr[:], mac[:])")
314         g.P("   return macaddr, nil")
315         g.P("}")
316
317         // ToMAC method
318         g.P("func (x ", structName, ") ToMAC() ", netPkg.Ident("HardwareAddr"), " {")
319         g.P("   return ", netPkg.Ident("HardwareAddr"), "(x[:])")
320         g.P("}")
321
322         // String method
323         g.P("func (x ", structName, ") String() string {")
324         g.P("   return x.ToMAC().String()")
325         g.P("}")
326
327         // MarshalText method
328         g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
329         g.P("   return []byte(x.String()), nil")
330         g.P("}")
331
332         // UnmarshalText method
333         g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
334         g.P("   mac, err := Parse", structName, "(string(text))")
335         g.P("   if err != nil {")
336         g.P("           return err")
337         g.P("   }")
338         g.P("   *x = mac")
339         g.P("   return nil")
340         g.P("}")
341         g.P()
342 }
343
344 func genTimestampConversion(g *GenFile, structName string) {
345         // NewTimestamp method
346         g.P("func New", structName, "(t ", timePkg.Ident("Time"), ") ", structName, " {")
347         g.P("   sec := int64(t.Unix())")
348         g.P("   nsec := int32(t.Nanosecond())")
349         g.P("   ns := float64(sec) + float64(nsec / 1e9)")
350         g.P("   return ", structName, "(ns)")
351         g.P("}")
352
353         // ToTime method
354         g.P("func (x ", structName, ") ToTime() ", timePkg.Ident("Time"), " {")
355         g.P("   ns := int64(x * 1e9)")
356         g.P("   sec := ns / 1e9")
357         g.P("   nsec := ns % 1e9")
358         g.P("   return ", timePkg.Ident("Unix"), "(sec, nsec)")
359         g.P("}")
360
361         // String method
362         g.P("func (x ", structName, ") String() string {")
363         g.P("   return x.ToTime().String()")
364         g.P("}")
365
366         // MarshalText method
367         g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
368         g.P("   return []byte(x.ToTime().Format(", timePkg.Ident("RFC3339Nano"), ")), nil")
369         g.P("}")
370
371         // UnmarshalText method
372         g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
373         g.P("   t, err := ", timePkg.Ident("Parse"), "(", timePkg.Ident("RFC3339Nano"), ", string(text))")
374         g.P("   if err != nil {")
375         g.P("           return err")
376         g.P("   }")
377         g.P("   *x = New", structName, "(t)")
378         g.P("   return nil")
379         g.P("}")
380         g.P()
381 }