diff options
author | 2020-07-17 10:36:28 +0200 | |
---|---|---|
committer | 2020-07-17 11:43:41 +0200 | |
commit | d1f24d37bd447b64e402298bb8eb2479681facf9 (patch) | |
tree | a3fc21ba730a91d8a402c7a5bf9c614e3677c4fc /binapigen/vppapi.go | |
parent | 1548c7e12531e3d055567d761c580a1c7ff0ac40 (diff) |
Improve binapi generator
- simplified Size/Marshal/Unmarshal methods
- replace struc in unions with custom marshal/unmarshal
- fix imports in generated files
- fix mock adapter
- generate rpc service using low-level stream API (dumps generate control ping or stream msg..)
- move examples/binapi to binapi and generate all API for latest release
- add binapigen.Plugin for developing custom generator plugins
- optionally generate HTTP handlers (REST API) for RPC services
- add govpp program for browsing VPP API
Change-Id: I092e9ed2b0c17972b3476463c3d4b14dd76ed42b
Signed-off-by: Ondrej Fabry <ofabry@cisco.com>
Diffstat (limited to 'binapigen/vppapi.go')
-rw-r--r-- | binapigen/vppapi.go | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/binapigen/vppapi.go b/binapigen/vppapi.go new file mode 100644 index 0000000..7388ad5 --- /dev/null +++ b/binapigen/vppapi.go @@ -0,0 +1,211 @@ +// 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 ( + "log" + "sort" + + "git.fd.io/govpp.git/binapigen/vppapi" +) + +func SortFileObjectsByName(file *vppapi.File) { + sort.SliceStable(file.Imports, func(i, j int) bool { + return file.Imports[i] < file.Imports[j] + }) + sort.SliceStable(file.EnumTypes, func(i, j int) bool { + return file.EnumTypes[i].Name < file.EnumTypes[j].Name + }) + sort.Slice(file.AliasTypes, func(i, j int) bool { + return file.AliasTypes[i].Name < file.AliasTypes[j].Name + }) + sort.SliceStable(file.StructTypes, func(i, j int) bool { + return file.StructTypes[i].Name < file.StructTypes[j].Name + }) + sort.SliceStable(file.UnionTypes, func(i, j int) bool { + return file.UnionTypes[i].Name < file.UnionTypes[j].Name + }) + sort.SliceStable(file.Messages, func(i, j int) bool { + return file.Messages[i].Name < file.Messages[j].Name + }) + if file.Service != nil { + sort.Slice(file.Service.RPCs, func(i, j int) bool { + return file.Service.RPCs[i].Request < file.Service.RPCs[j].Request + }) + } +} + +func importedFiles(files []*vppapi.File, file *vppapi.File) []*vppapi.File { + var list []*vppapi.File + byName := func(s string) *vppapi.File { + for _, f := range files { + if f.Name == s { + return f + } + } + return nil + } + imported := map[string]struct{}{} + for _, imp := range file.Imports { + imp = normalizeImport(imp) + impFile := byName(imp) + if impFile == nil { + log.Fatalf("file %q not found", imp) + } + for _, nest := range importedFiles(files, impFile) { + if _, ok := imported[nest.Name]; !ok { + list = append(list, nest) + imported[nest.Name] = struct{}{} + } + } + if _, ok := imported[impFile.Name]; !ok { + list = append(list, impFile) + imported[impFile.Name] = struct{}{} + } + } + return list +} + +func SortFilesByImports(apifiles []*vppapi.File) { + dependsOn := func(file *vppapi.File, dep string) bool { + for _, imp := range importedFiles(apifiles, file) { + if imp.Name == dep { + return true + } + } + return false + } + sort.Slice(apifiles, func(i, j int) bool { + a := apifiles[i] + b := apifiles[j] + if dependsOn(a, b.Name) { + return false + } + if dependsOn(b, a.Name) { + return true + } + return len(b.Imports) > len(a.Imports) + }) +} + +func ListImportedTypes(apifiles []*vppapi.File, file *vppapi.File) []string { + var importedTypes []string + typeFiles := importedFiles(apifiles, file) + for _, t := range file.StructTypes { + var imported bool + for _, imp := range typeFiles { + for _, at := range imp.StructTypes { + if at.Name != t.Name { + continue + } + importedTypes = append(importedTypes, t.Name) + imported = true + break + } + if imported { + break + } + } + } + for _, t := range file.AliasTypes { + var imported bool + for _, imp := range typeFiles { + for _, at := range imp.AliasTypes { + if at.Name != t.Name { + continue + } + importedTypes = append(importedTypes, t.Name) + imported = true + break + } + if imported { + break + } + } + } + for _, t := range file.EnumTypes { + var imported bool + for _, imp := range typeFiles { + for _, at := range imp.EnumTypes { + if at.Name != t.Name { + continue + } + importedTypes = append(importedTypes, t.Name) + imported = true + break + } + if imported { + break + } + } + } + for _, t := range file.UnionTypes { + var imported bool + for _, imp := range typeFiles { + for _, at := range imp.UnionTypes { + if at.Name != t.Name { + continue + } + importedTypes = append(importedTypes, t.Name) + imported = true + break + } + if imported { + break + } + } + } + return importedTypes +} + +func RemoveImportedTypes(apifiles []*vppapi.File, apifile *vppapi.File) { + importedTypes := ListImportedTypes(apifiles, apifile) + isImportedType := func(s string) bool { + for _, t := range importedTypes { + if t == s { + return true + } + } + return false + } + var enums []vppapi.EnumType + for _, enumType := range apifile.EnumTypes { + if !isImportedType(enumType.Name) { + enums = append(enums, enumType) + } + } + var aliases []vppapi.AliasType + for _, aliasType := range apifile.AliasTypes { + if !isImportedType(aliasType.Name) { + aliases = append(aliases, aliasType) + } + } + var structs []vppapi.StructType + for _, structType := range apifile.StructTypes { + if !isImportedType(structType.Name) { + structs = append(structs, structType) + } + } + var unions []vppapi.UnionType + for _, unionType := range apifile.UnionTypes { + if !isImportedType(unionType.Name) { + unions = append(unions, unionType) + } + } + apifile.EnumTypes = enums + apifile.AliasTypes = aliases + apifile.StructTypes = structs + apifile.UnionTypes = unions +} |