From 94620e85f0bdbb054af07ce3670fadc1f76cfdf0 Mon Sep 17 00:00:00 2001 From: Ondrej Fabry Date: Thu, 18 Jun 2020 08:22:13 +0200 Subject: Refactored binapi generator with message encoding Change-Id: I5a6abb68b9d058866f94818169300e5c2fc43895 Signed-off-by: Ondrej Fabry --- binapigen/types.go | 271 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 271 insertions(+) create mode 100644 binapigen/types.go (limited to 'binapigen/types.go') diff --git a/binapigen/types.go b/binapigen/types.go new file mode 100644 index 0000000..0dbbeb1 --- /dev/null +++ b/binapigen/types.go @@ -0,0 +1,271 @@ +// 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 + +import ( + "strings" + + "github.com/sirupsen/logrus" +) + +// define api +const ( + defineApiPrefix = "vl_api_" + defineApiSuffix = "_t" +) + +// BaseType represents base types in VPP binary API. +type BaseType int + +const ( + U8 BaseType = iota + 1 + I8 + U16 + I16 + U32 + I32 + U64 + I64 + F64 + BOOL + STRING +) + +var ( + BaseTypes = map[BaseType]string{ + U8: "u8", + I8: "i8", + U16: "u16", + I16: "i16", + U32: "u32", + I32: "i32", + U64: "u64", + I64: "i64", + F64: "f64", + BOOL: "bool", + STRING: "string", + } + BaseTypeNames = map[string]BaseType{ + "u8": U8, + "i8": I8, + "u16": U16, + "i16": I16, + "u32": U32, + "i32": I32, + "u64": U64, + "i64": I64, + "f64": F64, + "bool": BOOL, + "string": STRING, + } +) + +var BaseTypeSizes = map[BaseType]int{ + U8: 1, + I8: 1, + U16: 2, + I16: 2, + U32: 4, + I32: 4, + U64: 8, + I64: 8, + F64: 8, + BOOL: 1, + STRING: 1, +} + +type Kind int + +const ( + _ = iota + Uint8Kind + Int8Kind + Uint16Kind + Int16Kind + Uint32Kind + Int32Kind + Uint64Kind + Int64Kind + Float64Kind + BoolKind + StringKind + EnumKind + AliasKind + StructKind + UnionKind + MessageKind +) + +// toApiType returns name that is used as type reference in VPP binary API +func toApiType(name string) string { + return defineApiPrefix + name + defineApiSuffix +} + +func fromApiType(typ string) string { + name := typ + name = strings.TrimPrefix(name, defineApiPrefix) + name = strings.TrimSuffix(name, defineApiSuffix) + return name +} + +func getSizeOfType(module *File, typ *Struct) (size int) { + for _, field := range typ.Fields { + enum := getEnumByRef(module, field.Type) + if enum != nil { + size += getSizeOfBinapiTypeLength(enum.Type, field.Length) + continue + } + size += getSizeOfBinapiTypeLength(field.Type, field.Length) + } + return size +} + +func getEnumByRef(file *File, ref string) *Enum { + for _, typ := range file.Enums { + if ref == toApiType(typ.Name) { + return typ + } + } + return nil +} + +func getTypeByRef(file *File, ref string) *Struct { + for _, typ := range file.Structs { + if ref == toApiType(typ.Name) { + return typ + } + } + return nil +} + +func getAliasByRef(file *File, ref string) *Alias { + for _, alias := range file.Aliases { + if ref == toApiType(alias.Name) { + return alias + } + } + return nil +} + +func getUnionByRef(file *File, ref string) *Union { + for _, union := range file.Unions { + if ref == toApiType(union.Name) { + return union + } + } + return nil +} + +func getBinapiTypeSize(binapiType string) (size int) { + typName := BaseTypeNames[binapiType] + return BaseTypeSizes[typName] +} + +// binapiTypes is a set of types used VPP binary API for translation to Go types +var binapiTypes = map[string]string{ + "u8": "uint8", + "i8": "int8", + "u16": "uint16", + "i16": "int16", + "u32": "uint32", + "i32": "int32", + "u64": "uint64", + "i64": "int64", + "f64": "float64", +} +var BaseTypesGo = map[BaseType]string{ + U8: "uint8", + I8: "int8", + U16: "uint16", + I16: "int16", + U32: "uint32", + I32: "int32", + U64: "uint64", + I64: "int64", + F64: "float64", + BOOL: "bool", + STRING: "string", +} + +func getActualType(file *File, typ string) (actual string) { + for _, enum := range file.Enums { + if enum.GoName == typ { + return enum.Type + } + } + for _, alias := range file.Aliases { + if alias.GoName == typ { + return alias.Type + } + } + return typ +} + +// convertToGoType translates the VPP binary API type into Go type +func convertToGoType(file *File, binapiType string) (typ string) { + if t, ok := binapiTypes[binapiType]; ok { + // basic types + typ = t + } else if r, ok := file.refmap[binapiType]; ok { + // specific types (enums/types/unions) + typ = camelCaseName(r) + } else { + switch binapiType { + case "bool", "string": + typ = binapiType + default: + // fallback type + logrus.Warnf("found unknown VPP binary API type %q, using byte", binapiType) + typ = "byte" + } + } + return typ +} + +func getSizeOfBinapiTypeLength(typ string, length int) (size int) { + if n := getBinapiTypeSize(typ); n > 0 { + if length > 0 { + return n * length + } else { + return n + } + } + + return +} + +func getUnionSize(file *File, union *Union) (maxSize int) { + for _, field := range union.Fields { + typ := getTypeByRef(file, field.Type) + if typ != nil { + if size := getSizeOfType(file, typ); size > maxSize { + maxSize = size + } + continue + } + alias := getAliasByRef(file, field.Type) + if alias != nil { + if size := getSizeOfBinapiTypeLength(alias.Type, alias.Length); size > maxSize { + maxSize = size + } + continue + } else { + logf("no type or alias found for union %s field type %q", union.Name, field.Type) + continue + } + } + logf("getUnionSize: %s %+v max=%v", union.Name, union.Fields, maxSize) + return +} -- cgit 1.2.3-korg