From b8743f90b835a18871405fd318ba8a5e1a72eafb Mon Sep 17 00:00:00 2001 From: Ondrej Fabry Date: Mon, 27 May 2019 09:03:12 +0200 Subject: Add support for field meta data to binapi-generator Change-Id: Id0164d36727d070e395a522000f2e09ee5444bd0 Signed-off-by: Ondrej Fabry --- cmd/binapi-generator/generate.go | 23 ++++++++++++++++++-- cmd/binapi-generator/objects.go | 6 +++++ cmd/binapi-generator/parse.go | 47 ++++++++++++++++++++++++++++++---------- 3 files changed, 62 insertions(+), 14 deletions(-) diff --git a/cmd/binapi-generator/generate.go b/cmd/binapi-generator/generate.go index f22a035..64d1071 100644 --- a/cmd/binapi-generator/generate.go +++ b/cmd/binapi-generator/generate.go @@ -591,17 +591,36 @@ func generateField(ctx *context, w io.Writer, fields []Field, i int) { } fmt.Fprintf(w, "\t%s %s", fieldName, fieldType) + fieldTags := map[string]string{} + if field.Length > 0 { // fixed size array - fmt.Fprintf(w, "\t`struc:\"[%d]%s\"`", field.Length, dataType) + fieldTags["struc"] = fmt.Sprintf("[%d]%s", field.Length, dataType) } else { for _, f := range fields { if f.SizeFrom == field.Name { // variable sized array sizeOfName := camelCaseName(f.Name) - fmt.Fprintf(w, "\t`struc:\"sizeof=%s\"`", sizeOfName) + fieldTags["struc"] = fmt.Sprintf("sizeof=%s", sizeOfName) + } + } + } + + if field.Meta.Limit > 0 { + fieldTags["binapi"] = fmt.Sprintf(",limit=%d", field.Meta.Limit) + } + + if len(fieldTags) > 0 { + fmt.Fprintf(w, "\t`") + var i int + for n, t := range fieldTags { + if i > 0 { + fmt.Fprintf(w, " ") } + i++ + fmt.Fprintf(w, `%s:"%s"`, n, t) } + fmt.Fprintf(w, "`") } fmt.Fprintln(w) diff --git a/cmd/binapi-generator/objects.go b/cmd/binapi-generator/objects.go index 75c7581..8f5e8ef 100644 --- a/cmd/binapi-generator/objects.go +++ b/cmd/binapi-generator/objects.go @@ -54,6 +54,12 @@ type Field struct { Type string Length int SizeFrom string + Meta FieldMeta +} + +// FieldMeta represents VPP binary API meta info for field +type FieldMeta struct { + Limit int } // Union represents VPP binary API union diff --git a/cmd/binapi-generator/parse.go b/cmd/binapi-generator/parse.go index 4138ac6..662ed34 100644 --- a/cmd/binapi-generator/parse.go +++ b/cmd/binapi-generator/parse.go @@ -59,6 +59,11 @@ const ( serviceNoReply = "null" ) +// field meta info +const ( + fieldMetaLimit = "limit" +) + // parsePackage parses provided JSON data into objects prepared for code generation func parsePackage(ctx *context, jsonRoot *jsongo.JSONNode) (*Package, error) { logf(" %s (version: %s) contains: %d services, %d messages, %d types, %d enums, %d unions, %d aliases", @@ -438,27 +443,45 @@ func parseField(ctx *context, field *jsongo.JSONNode) (*Field, error) { if !ok { return nil, fmt.Errorf("field name is %T, not a string", field.At(1).Get()) } - var fieldLength float64 + + f := &Field{ + Name: fieldName, + Type: fieldType, + } + if field.Len() >= 3 { - fieldLength, ok = field.At(2).Get().(float64) - if !ok { - return nil, fmt.Errorf("field length is %T, not float64", field.At(2).Get()) + if field.At(2).GetType() == jsongo.TypeValue { + fieldLength, ok := field.At(2).Get().(float64) + if !ok { + return nil, fmt.Errorf("field length is %T, not float64", field.At(2).Get()) + } + f.Length = int(fieldLength) + } else if field.At(2).GetType() == jsongo.TypeMap { + fieldMeta := field.At(2) + + for _, key := range fieldMeta.GetKeys() { + metaNode := fieldMeta.At(key) + + switch metaName := key.(string); metaName { + case fieldMetaLimit: + f.Meta.Limit = int(metaNode.Get().(float64)) + default: + log.Warnf("unknown meta info (%s) for field (%s)", metaName, fieldName) + } + } + } else { + return nil, errors.New("invalid JSON for field specified") } } - var fieldLengthFrom string if field.Len() >= 4 { - fieldLengthFrom, ok = field.At(3).Get().(string) + fieldLengthFrom, ok := field.At(3).Get().(string) if !ok { return nil, fmt.Errorf("field length from is %T, not a string", field.At(3).Get()) } + f.SizeFrom = fieldLengthFrom } - return &Field{ - Name: fieldName, - Type: fieldType, - Length: int(fieldLength), - SizeFrom: fieldLengthFrom, - }, nil + return f, nil } // parseService parses VPP binary API service object from JSON node -- cgit 1.2.3-korg