1 // Copyright (c) 2020 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.
21 "github.com/sirupsen/logrus"
26 defineApiPrefix = "vl_api_"
27 defineApiSuffix = "_t"
30 // BaseType represents base types in VPP binary API.
34 U8 BaseType = iota + 1
48 BaseTypes = map[BaseType]string{
61 BaseTypeNames = map[string]BaseType{
76 var BaseTypeSizes = map[BaseType]int{
112 // toApiType returns name that is used as type reference in VPP binary API
113 func toApiType(name string) string {
114 return defineApiPrefix + name + defineApiSuffix
117 func fromApiType(typ string) string {
119 name = strings.TrimPrefix(name, defineApiPrefix)
120 name = strings.TrimSuffix(name, defineApiSuffix)
124 func getSizeOfType(module *File, typ *Struct) (size int) {
125 for _, field := range typ.Fields {
126 enum := getEnumByRef(module, field.Type)
128 size += getSizeOfBinapiTypeLength(enum.Type, field.Length)
131 size += getSizeOfBinapiTypeLength(field.Type, field.Length)
136 func getEnumByRef(file *File, ref string) *Enum {
137 for _, typ := range file.Enums {
138 if ref == toApiType(typ.Name) {
145 func getTypeByRef(file *File, ref string) *Struct {
146 for _, typ := range file.Structs {
147 if ref == toApiType(typ.Name) {
154 func getAliasByRef(file *File, ref string) *Alias {
155 for _, alias := range file.Aliases {
156 if ref == toApiType(alias.Name) {
163 func getUnionByRef(file *File, ref string) *Union {
164 for _, union := range file.Unions {
165 if ref == toApiType(union.Name) {
172 func getBinapiTypeSize(binapiType string) (size int) {
173 typName := BaseTypeNames[binapiType]
174 return BaseTypeSizes[typName]
177 // binapiTypes is a set of types used VPP binary API for translation to Go types
178 var binapiTypes = map[string]string{
189 var BaseTypesGo = map[BaseType]string{
203 func getActualType(file *File, typ string) (actual string) {
204 for _, enum := range file.Enums {
205 if enum.GoName == typ {
209 for _, alias := range file.Aliases {
210 if alias.GoName == typ {
217 // convertToGoType translates the VPP binary API type into Go type.
218 // Imported types are with import prefix.
219 func convertToGoType(file *File, binapiType string) (typ string) {
220 if t, ok := binapiTypes[binapiType]; ok {
223 } else if r, ok := file.refmap[binapiType]; ok {
224 // specific types (enums/types/unions)
226 typ = camelCaseName(r)
227 // look in imports using name and type name eventually
228 if imp, ok := file.imports[typ]; ok {
229 prefix = fmt.Sprintf("%s.", imp)
230 } else if imp, ok := file.imports[fromApiType(binapiType)]; ok {
231 prefix = fmt.Sprintf("%s.", imp)
233 typ = fmt.Sprintf("%s%s", prefix, typ)
236 case "bool", "string":
240 logrus.Warnf("found unknown VPP binary API type %q, using byte", binapiType)
247 func getSizeOfBinapiTypeLength(typ string, length int) (size int) {
248 if n := getBinapiTypeSize(typ); n > 0 {
259 func getUnionSize(file *File, union *Union) (maxSize int) {
260 for _, field := range union.Fields {
261 typ := getTypeByRef(file, field.Type)
263 if size := getSizeOfType(file, typ); size > maxSize {
268 alias := getAliasByRef(file, field.Type)
270 if size := getSizeOfBinapiTypeLength(alias.Type, alias.Length); size > maxSize {
275 logf("no type or alias found for union %s field type %q", union.Name, field.Type)
279 logf("getUnionSize: %s %+v max=%v", union.Name, union.Fields, maxSize)