aboutsummaryrefslogtreecommitdiffstats
path: root/binapigen/types.go
diff options
context:
space:
mode:
Diffstat (limited to 'binapigen/types.go')
-rw-r--r--binapigen/types.go271
1 files changed, 271 insertions, 0 deletions
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
+}