Add support for field meta data to binapi-generator 32/19832/1
authorOndrej Fabry <ofabry@cisco.com>
Mon, 27 May 2019 07:03:12 +0000 (09:03 +0200)
committerOndrej Fabry <ofabry@cisco.com>
Mon, 27 May 2019 07:03:12 +0000 (09:03 +0200)
Change-Id: Id0164d36727d070e395a522000f2e09ee5444bd0
Signed-off-by: Ondrej Fabry <ofabry@cisco.com>
cmd/binapi-generator/generate.go
cmd/binapi-generator/objects.go
cmd/binapi-generator/parse.go

index f22a035..64d1071 100644 (file)
@@ -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)
index 75c7581..8f5e8ef 100644 (file)
@@ -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
index 4138ac6..662ed34 100644 (file)
@@ -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