1 // Copyright (c) 2019 Cisco and/or its affiliates.
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:
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
22 "github.com/sirupsen/logrus"
25 // toApiType returns name that is used as type reference in VPP binary API
26 func toApiType(name string) string {
27 return fmt.Sprintf("vl_api_%s_t", name)
30 // binapiTypes is a set of types used VPP binary API for translation to Go types
31 var binapiTypes = map[string]string{
43 func getBinapiTypeSize(binapiType string) int {
44 if _, ok := binapiTypes[binapiType]; ok {
45 b, err := strconv.Atoi(strings.TrimLeft(binapiType, "uif"))
53 // convertToGoType translates the VPP binary API type into Go type
54 func convertToGoType(ctx *context, binapiType string) (typ string) {
55 if t, ok := binapiTypes[binapiType]; ok {
58 } else if r, ok := ctx.packageData.RefMap[binapiType]; ok {
59 // specific types (enums/types/unions)
60 typ = camelCaseName(r)
63 case "bool", "string":
67 logrus.Warnf("found unknown VPP binary API type %q, using byte", binapiType)
74 func getSizeOfType(ctx *context, typ *Type) (size int) {
75 for _, field := range typ.Fields {
76 enum := getEnumByRef(ctx, field.Type)
78 size += getSizeOfBinapiTypeLength(enum.Type, field.Length)
81 size += getSizeOfBinapiTypeLength(field.Type, field.Length)
86 func getSizeOfBinapiTypeLength(typ string, length int) (size int) {
87 if n := getBinapiTypeSize(typ); n > 0 {
98 func getEnumByRef(ctx *context, ref string) *Enum {
99 for _, typ := range ctx.packageData.Enums {
100 if ref == toApiType(typ.Name) {
107 func getTypeByRef(ctx *context, ref string) *Type {
108 for _, typ := range ctx.packageData.Types {
109 if ref == toApiType(typ.Name) {
116 func getAliasByRef(ctx *context, ref string) *Alias {
117 for _, alias := range ctx.packageData.Aliases {
118 if ref == toApiType(alias.Name) {
125 func getUnionSize(ctx *context, union *Union) (maxSize int) {
126 for _, field := range union.Fields {
127 typ := getTypeByRef(ctx, field.Type)
129 if size := getSizeOfType(ctx, typ); size > maxSize {
134 alias := getAliasByRef(ctx, field.Type)
136 if size := getSizeOfBinapiTypeLength(alias.Type, alias.Length); size > maxSize {
141 logf("no type or alias found for union %s field type %q", union.Name, field.Type)
145 logf("getUnionSize: %s %+v max=%v", union.Name, union.Fields, maxSize)