// field meta info
const (
- fieldMetaLimit = "limit"
+ fieldMetaLimit = "limit"
+ fieldMetaDefault = "default"
)
// module options
)
// parsePackage parses provided JSON data into objects prepared for code generation
-func parsePackage(ctx *context, jsonRoot *jsongo.JSONNode) (*Package, error) {
+func parsePackage(ctx *context, jsonRoot *jsongo.Node) (*Package, error) {
pkg := Package{
- Name: ctx.packageName,
- RefMap: make(map[string]string),
+ Name: ctx.packageName,
+ RefMap: make(map[string]string),
+ Imports: map[string]Import{},
}
// parse CRC for API version
// parse enums
enums := jsonRoot.Map(objEnums)
- pkg.Enums = make([]Enum, enums.Len())
+ pkg.Enums = make([]Enum, 0)
for i := 0; i < enums.Len(); i++ {
enumNode := enums.At(i)
if err != nil {
return nil, err
}
- pkg.Enums[i] = *enum
- pkg.RefMap[toApiType(enum.Name)] = enum.Name
+
+ enumApi := toApiType(enum.Name)
+ if _, ok := pkg.RefMap[enumApi]; ok {
+ logf("enum %v already known", enumApi)
+ continue
+ }
+ pkg.RefMap[enumApi] = enum.Name
+ pkg.Enums = append(pkg.Enums, *enum)
}
// sort enums
sort.SliceStable(pkg.Enums, func(i, j int) bool {
// parse aliases
aliases := jsonRoot.Map(objAliases)
if aliases.GetType() == jsongo.TypeMap {
- pkg.Aliases = make([]Alias, aliases.Len())
- for i, key := range aliases.GetKeys() {
+ pkg.Aliases = make([]Alias, 0)
+ for _, key := range aliases.GetKeys() {
aliasNode := aliases.At(key)
alias, err := parseAlias(ctx, key.(string), aliasNode)
if err != nil {
return nil, err
}
- pkg.Aliases[i] = *alias
- pkg.RefMap[toApiType(alias.Name)] = alias.Name
+
+ aliasApi := toApiType(alias.Name)
+ if _, ok := pkg.RefMap[aliasApi]; ok {
+ logf("alias %v already known", aliasApi)
+ continue
+ }
+ pkg.RefMap[aliasApi] = alias.Name
+ pkg.Aliases = append(pkg.Aliases, *alias)
}
}
// sort aliases to ensure consistent order
// parse types
types := jsonRoot.Map(objTypes)
- pkg.Types = make([]Type, types.Len())
+ pkg.Types = make([]Type, 0)
for i := 0; i < types.Len(); i++ {
typNode := types.At(i)
if err != nil {
return nil, err
}
- pkg.Types[i] = *typ
- pkg.RefMap[toApiType(typ.Name)] = typ.Name
+
+ typApi := toApiType(typ.Name)
+ if _, ok := pkg.RefMap[typApi]; ok {
+ logf("type %v already known", typApi)
+ continue
+ }
+ pkg.RefMap[typApi] = typ.Name
+ pkg.Types = append(pkg.Types, *typ)
}
// sort types
sort.SliceStable(pkg.Types, func(i, j int) bool {
// parse unions
unions := jsonRoot.Map(objUnions)
- pkg.Unions = make([]Union, unions.Len())
+ pkg.Unions = make([]Union, 0)
for i := 0; i < unions.Len(); i++ {
unionNode := unions.At(i)
if err != nil {
return nil, err
}
- pkg.Unions[i] = *union
- pkg.RefMap[toApiType(union.Name)] = union.Name
+
+ unionApi := toApiType(union.Name)
+ if _, ok := pkg.RefMap[unionApi]; ok {
+ logf("union %v already known", unionApi)
+ continue
+ }
+ pkg.RefMap[unionApi] = union.Name
+ pkg.Unions = append(pkg.Unions, *union)
}
// sort unions
sort.SliceStable(pkg.Unions, func(i, j int) bool {
}
// parseEnum parses VPP binary API enum object from JSON node
-func parseEnum(ctx *context, enumNode *jsongo.JSONNode) (*Enum, error) {
+func parseEnum(ctx *context, enumNode *jsongo.Node) (*Enum, error) {
if enumNode.Len() == 0 || enumNode.At(0).GetType() != jsongo.TypeValue {
return nil, errors.New("invalid JSON for enum specified")
}
}
// parseUnion parses VPP binary API union object from JSON node
-func parseUnion(ctx *context, unionNode *jsongo.JSONNode) (*Union, error) {
+func parseUnion(ctx *context, unionNode *jsongo.Node) (*Union, error) {
if unionNode.Len() == 0 || unionNode.At(0).GetType() != jsongo.TypeValue {
return nil, errors.New("invalid JSON for union specified")
}
}
// parseType parses VPP binary API type object from JSON node
-func parseType(ctx *context, typeNode *jsongo.JSONNode) (*Type, error) {
+func parseType(ctx *context, typeNode *jsongo.Node) (*Type, error) {
if typeNode.Len() == 0 || typeNode.At(0).GetType() != jsongo.TypeValue {
return nil, errors.New("invalid JSON for type specified")
}
}
// parseAlias parses VPP binary API alias object from JSON node
-func parseAlias(ctx *context, aliasName string, aliasNode *jsongo.JSONNode) (*Alias, error) {
+func parseAlias(ctx *context, aliasName string, aliasNode *jsongo.Node) (*Alias, error) {
if aliasNode.Len() == 0 || aliasNode.At(aliasTypeField).GetType() != jsongo.TypeValue {
return nil, errors.New("invalid JSON for alias specified")
}
}
// parseMessage parses VPP binary API message object from JSON node
-func parseMessage(ctx *context, msgNode *jsongo.JSONNode) (*Message, error) {
+func parseMessage(ctx *context, msgNode *jsongo.Node) (*Message, error) {
if msgNode.Len() == 0 || msgNode.At(0).GetType() != jsongo.TypeValue {
return nil, errors.New("invalid JSON for message specified")
}
}
// parseField parses VPP binary API object field from JSON node
-func parseField(ctx *context, field *jsongo.JSONNode) (*Field, error) {
+func parseField(ctx *context, field *jsongo.Node) (*Field, error) {
if field.Len() < 2 || field.At(0).GetType() != jsongo.TypeValue || field.At(1).GetType() != jsongo.TypeValue {
return nil, errors.New("invalid JSON for field specified")
}
}
if field.Len() >= 3 {
- if field.At(2).GetType() == jsongo.TypeValue {
+ switch field.At(2).GetType() {
+ case 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 {
+ f.SpecifiedLen = true
+
+ case jsongo.TypeMap:
fieldMeta := field.At(2)
for _, key := range fieldMeta.GetKeys() {
switch metaName := key.(string); metaName {
case fieldMetaLimit:
f.Meta.Limit = int(metaNode.Get().(float64))
+ case fieldMetaDefault:
+ f.Meta.Default = fmt.Sprint(metaNode.Get())
default:
logrus.Warnf("unknown meta info (%s) for field (%s)", metaName, fieldName)
}
}
- } else {
+ default:
return nil, errors.New("invalid JSON for field specified")
}
}
}
// parseService parses VPP binary API service object from JSON node
-func parseService(ctx *context, svcName string, svcNode *jsongo.JSONNode) (*Service, error) {
+func parseService(ctx *context, svcName string, svcNode *jsongo.Node) (*Service, error) {
if svcNode.Len() == 0 || svcNode.At(replyField).GetType() != jsongo.TypeValue {
return nil, errors.New("invalid JSON for service specified")
}