github.com/urso/go-structform@v0.0.2/gotype/unfold_map.yml (about)

     1  import:
     2    - unfold_templates.yml
     3  
     4  main: |
     5    package gotype
     6  
     7    import "github.com/urso/go-structform"
     8  
     9    {{/* defined 'lifted' pointer map unfolders into reflection based unfolders */}}
    10    var (
    11      unfolderReflMapIfc = liftGoUnfolder(newUnfolderMapIfc())
    12      {{ range data.primitiveTypes }}
    13      {{ $t := capitalize . }}
    14        unfolderReflMap{{ $t }} = liftGoUnfolder(newUnfolderMap{{ $t }}())
    15      {{ end }}
    16    )
    17  
    18    {{/* define pointer based unfolder types */}}
    19    {{ invoke "makeTypeWithName" "name" "Ifc" "type" "interface{}" }}
    20    {{ template "makeType" "bool" }}
    21    {{ template "makeType" "string" }}
    22    {{ range .numTypes }}
    23      {{ template "makeType" . }}
    24    {{ end }}
    25  
    26    {{/* create value visitor callbacks */}}
    27    {{ invoke "onIfcFns" "name" "unfolderMapIfc" "fn" "put" }}
    28    {{ invoke "onBoolFns" "name" "unfolderMapBool" "fn" "put" }}
    29    {{ invoke "onStringFns" "name" "unfolderMapString" "fn" "put" }}
    30    {{ range .numTypes }}
    31      {{ $type := . }}
    32      {{ $name := capitalize $type | printf "unfolderMap%v" }}
    33      {{ invoke "onNumberFns" "name" $name "type" $type "fn" "put" }}
    34    {{ end }}
    35  
    36    {{ template "mapIfc" }}
    37  
    38  
    39  # makeTypeWithName(name, type)
    40  templates.makeTypeWithName: |
    41    {{ $type := .type }}
    42    {{ $name := capitalize .name | printf "unfolderMap%v" }}
    43    {{ $startName := capitalize .name | printf "unfoldMapStart%v" }}
    44    {{ $keyName := capitalize .name | printf "unfoldMapKey%v" }}
    45  
    46    {{ invoke "makeUnfoldType" "name" $name }}
    47    {{ invoke "makeUnfoldType" "name" $startName "base" "unfolderErrObjectStart" }}
    48    {{ invoke "makeUnfoldType" "name" $keyName "base" "unfolderErrExpectKey" }}
    49  
    50    func (u *{{ $name }} ) initState(ctx *unfoldCtx, ptr unsafe.Pointer) {
    51      ctx.unfolder.push(new{{ $keyName | capitalize}}())
    52      ctx.unfolder.push(new{{ $startName | capitalize}}())
    53      ctx.ptr.push(ptr)
    54    }
    55  
    56    func (u * {{ $keyName }} ) cleanup(ctx *unfoldCtx) {
    57      ctx.unfolder.pop()
    58      ctx.ptr.pop()
    59    }
    60  
    61    func (u * {{ $startName }}) cleanup(ctx *unfoldCtx) {
    62      ctx.unfolder.pop()
    63    }
    64  
    65  
    66    func (u *{{ $name }} ) ptr(ctx *unfoldCtx) *map[string]{{ $type }} {
    67      return (*map[string]{{ $type }})(ctx.ptr.current)
    68    }
    69  
    70  
    71    func (u *{{ $startName }} ) OnObjectStart(ctx *unfoldCtx, l int, baseType structform.BaseType) error {
    72      // TODO: validate baseType
    73  
    74      u.cleanup(ctx)
    75      return nil
    76    }
    77  
    78    func (u *{{ $keyName }} ) OnKeyRef(ctx *unfoldCtx, key []byte) error {
    79      return u.OnKey(ctx, ctx.keyCache.get(key))
    80    }
    81  
    82    func (u *{{ $keyName }} ) OnKey(ctx *unfoldCtx, key string) error {
    83      ctx.key.push(key)
    84      ctx.unfolder.current = new{{ $name | capitalize }}()
    85      return nil
    86    }
    87  
    88    func (u *{{ $keyName }} ) OnObjectFinished(ctx *unfoldCtx) error {
    89      u.cleanup(ctx)
    90      return nil
    91    }
    92  
    93    func (u *{{ $name }} ) put(ctx *unfoldCtx, v {{ $type }}) error {
    94      to := u.ptr(ctx)
    95      if *to == nil {
    96        *to = map[string]{{ $type }}{}
    97      }
    98      (*to)[ctx.key.pop()] = v
    99  
   100      ctx.unfolder.current = new{{ $keyName | capitalize }}()
   101      return nil
   102    }
   103  
   104  templates.mapIfc: |
   105    func unfoldIfcStartSubMap(ctx *unfoldCtx, l int, baseType structform.BaseType) error {
   106      _, ptr, unfolder := makeMapPtr(ctx, l, baseType)
   107      ctx.ptr.push(ptr)
   108      ctx.baseType.push(baseType)
   109      unfolder.initState(ctx, ptr)
   110      return ctx.unfolder.current.OnObjectStart(ctx, l, baseType)
   111    }
   112  
   113    func unfoldIfcFinishSubMap(ctx *unfoldCtx) (interface{}, error) {
   114      child := ctx.ptr.pop()
   115      bt := ctx.baseType.pop()
   116      switch bt {
   117      {{ range $bt, $gt := data.mapTypes }}
   118      case structform.{{ $bt }}:
   119        ctx.buf.release()
   120        return *(*map[string]{{ $gt }})(child), nil
   121      {{ end }}
   122      default:
   123        return nil, errTODO()
   124      }
   125    }
   126  
   127    func makeMapPtr(ctx *unfoldCtx, l int, bt structform.BaseType) (interface{}, unsafe.Pointer, ptrUnfolder) {
   128      switch bt {
   129      {{ range $bt, $gt := data.mapTypes }}
   130      case structform.{{ $bt }}:
   131        sz := unsafe.Sizeof(map[string]{{ $gt }}{})
   132        ptr := ctx.buf.alloc(int(sz))
   133        to := (*map[string]{{ $gt }})(ptr)
   134        {{ if or (eq $bt "AnyType")  (eq $bt "ZeroType") }}
   135          unfolder := newUnfolderMapIfc()
   136        {{ else }}
   137          unfolder := newUnfolderMap{{ $gt | capitalize }}()
   138        {{ end }}
   139        return to, ptr, unfolder
   140      {{ end }}
   141      default:
   142        panic("invalid type code")
   143        return nil, nil, nil
   144      }
   145    }