github.com/geniusesgroup/libgo@v0.0.0-20220713101832-828057a9d3d4/syllab/generator.go (about) 1 /* For license and copyright information please see LEGAL file in repository */ 2 3 package syllab 4 5 import ( 6 "bytes" 7 "go/ast" 8 "go/parser" 9 "go/token" 10 "reflect" 11 "strconv" 12 "strings" 13 14 "../assets" 15 "../log" 16 ) 17 18 /* 19 Before pass file to CompleteMethods(), dev must add needed methods to desire type by below template! 20 Otherwise panic may occur due to improve performance we don't check some bad situation!! 21 For just syllabDecoder() method you can omit syllabStackLen() & syllabLen() 22 23 func ({{DesireName}} *{{DesireType}}) syllabDecoder(buf []byte) (err error) { 24 return 25 } 26 27 func ({{DesireName}} *{{DesireType}}) SyllabDecoder(buf []byte, stackIndex int) { 28 return 29 } 30 31 func ({{DesireName}} *{{DesireType}}) syllabEncoder(buf []byte) {} 32 33 func ({{DesireName}} *{{DesireType}}) syllabEncoder() (buf []byte) { 34 buf = make([]byte, {{DesireName}}.syllabLen()) 35 return 36 } 37 38 func ({{DesireName}} *{{DesireType}}) SyllabEncoder(buf []byte, stackIndex, heapIndex uint32) (hi uint32) { 39 return heapIndex 40 } 41 42 func ({{DesireName}} *{{DesireType}}) syllabStackLen() (ln uint32) { 43 return 44 } 45 46 func ({{DesireName}} *{{DesireType}}) syllabHeapLen() (ln uint32) { 47 return 48 } 49 50 func ({{DesireName}} *{{DesireType}}) syllabLen() (ln int) { 51 return int({{DesireName}}.SyllabStackLen() + {{DesireName}}.syllabHeapLen()) 52 } 53 */ 54 55 // GenerationOptions indicate generator behavior! 56 type GenerationOptions struct { 57 UnSafe bool // true means don't copy data from given payload||buffer and just point to it for decoding fields! buffer can't GC until decoded struct free! 58 ForceUpdate bool // true means delete exiting codes and update encoders && decoders codes anyway! 59 } 60 61 // CompleteMethods use to update given go files and complete Syllab encoder&&decoder to any struct type in it! 62 // It will overwrite given file methods! If you need it clone it before pass it here! 63 func CompleteMethods(file *assets.File, gos *GenerationOptions) (err error) { 64 var fileSet *token.FileSet = token.NewFileSet() 65 var fileParsed *ast.File 66 fileParsed, err = parser.ParseFile(fileSet, "", file.Data, parser.ParseComments) 67 if err != nil { 68 return 69 } 70 71 var fileReplaces = make([]assets.ReplaceReq, 0, 4) 72 var sm = syllabMaker{ 73 Options: gos, 74 Types: map[string]*ast.TypeSpec{}, 75 } 76 77 // find syllabDecoder || syllabEncoder method 78 for _, decl := range fileParsed.Decls { 79 switch d := decl.(type) { 80 case *ast.GenDecl: 81 for _, gDecl := range d.Specs { 82 switch gd := gDecl.(type) { 83 case *ast.TypeSpec: 84 sm.Types[gd.Name.Name] = gd 85 } 86 } 87 case *ast.FuncDecl: 88 if d.Recv != nil { 89 if sm.RN != d.Recv.List[0].Names[0].Name { 90 sm.reset() 91 sm.RN = d.Recv.List[0].Names[0].Name 92 sm.FRN = d.Recv.List[0].Names[0].Name + "." 93 sm.RTN = d.Recv.List[0].Type.(*ast.StarExpr).X.(*ast.Ident).Name 94 95 err = sm.make() 96 if err != nil { 97 return 98 } 99 100 sm.Encoder.WriteString(" return\n") 101 sm.Decoder.WriteString(" return\n") 102 sm.HeapSize.WriteString(" return\n") 103 } 104 105 // Just needed methods! 106 if d.Name.Name == "syllabDecoder" || d.Name.Name == "SyllabDecoder" { 107 fileReplaces = append(fileReplaces, assets.ReplaceReq{ 108 Data: sm.Decoder.String(), 109 Start: int(d.Body.Lbrace), 110 End: int(d.Body.Rbrace) - 1}) // -1 to not remove end brace 111 } else if d.Name.Name == "syllabEncoder" || d.Name.Name == "SyllabEncoder" { 112 fileReplaces = append(fileReplaces, assets.ReplaceReq{ 113 Data: sm.Encoder.String(), 114 Start: int(d.Body.Lbrace), 115 End: int(d.Body.Rbrace) - 1}) // -1 to not remove end brace 116 } else if d.Name.Name == "syllabStackLen" || d.Name.Name == "SyllabStackLen" { 117 fileReplaces = append(fileReplaces, assets.ReplaceReq{ 118 Data: "\n return " + sm.getSLIAsString(0) + "\n", 119 Start: int(d.Body.Lbrace), 120 End: int(d.Body.Rbrace) - 1}) // -1 to not remove end brace 121 } else if d.Name.Name == "syllabHeapLen" || d.Name.Name == "SyllabHeapLen" { 122 fileReplaces = append(fileReplaces, assets.ReplaceReq{ 123 Data: sm.HeapSize.String(), 124 Start: int(d.Body.Lbrace), 125 End: int(d.Body.Rbrace) - 1}) // -1 to not remove end brace 126 } else if d.Name.Name == "syllabLen" || d.Name.Name == "SyllabLen" { 127 fileReplaces = append(fileReplaces, assets.ReplaceReq{ 128 Data: "\n return int(" + sm.RN + ".syllabStackLen() + " + sm.RN + ".syllabHeapLen())\n", 129 Start: int(d.Body.Lbrace), 130 End: int(d.Body.Rbrace) - 1}) // -1 to not remove end brace 131 } else if strings.HasPrefix(d.Name.Name, "get") { 132 // TODO::: 133 // fileReplaces = append(fileReplaces, assets.ReplaceReq{ 134 // Data: "\n return " + sm.RN + ".syllabStackLen() + " + sm.RN + ".syllabHeapLen()\n", 135 // Start: int(d.Body.Lbrace), 136 // End: int(d.Body.Rbrace) - 1}) // -1 to not remove end brace 137 } 138 } 139 } 140 } 141 142 file.Replace(fileReplaces) 143 file.State = assets.StateChanged 144 return 145 } 146 147 type syllabMaker struct { 148 Options *GenerationOptions 149 Types map[string]*ast.TypeSpec // All types 150 RN string // Receiver Name 151 FRN string // Flat Receiver Name e.g. req.Time. 152 RTN string // Receiver Type Name 153 LSI uint64 // Last Stack Index 154 StackSize bytes.Buffer // Stack len data to make slice size 155 HeapSize bytes.Buffer // Heap len data to make slice size 156 Encoder bytes.Buffer // Generated Data 157 Decoder bytes.Buffer // Generated Data 158 } 159 160 func (sm *syllabMaker) reset() { 161 sm.LSI = 0 162 sm.StackSize.Reset() 163 sm.HeapSize.Reset() 164 sm.Encoder.Reset() 165 sm.Decoder.Reset() 166 } 167 168 func (sm *syllabMaker) make() (err error) { 169 // Check needed type exist!! 170 typ, found := sm.Types[sm.RTN] 171 if !found { 172 return ErrSyllabNeededTypeNotExist 173 } 174 175 // Add some common data if ... 176 if sm.LSI == 0 { 177 sm.Decoder.WriteString( 178 "\n var add, ln uint32\n // var tempSlice []byte\n\n" + 179 " if uint32(len(buf)) < " + sm.RN + ".syllabStackLen() {\n" + 180 " err = syllab.ErrSyllabDecodeSmallSlice\n" + 181 " return\n" + 182 " }\n\n") 183 184 sm.Encoder.WriteString( 185 "\n // buf = make([]byte, " + sm.RN + ".syllabLen()+offset)\n" + 186 " var hsi uint32 = " + sm.RN + ".syllabStackLen() // Heap start index || Stack size!\n" + 187 " // var i, ln uint32 // len of strings, slices, maps, ...\n\n") 188 189 sm.HeapSize.WriteString("\n") 190 } 191 192 var fieldName string 193 switch structType := typ.Type.(type) { 194 default: 195 // Just occur if bad file pass to generator!! 196 return 197 case *ast.BasicLit: 198 // TODO::: very simple type 199 case *ast.StructType: 200 for _, structField := range structType.Fields.List { 201 if structField.Tag != nil && sm.checkFieldTag(structField.Tag.Value) { 202 continue 203 } 204 205 for _, field := range structField.Names { 206 fieldName = field.Name 207 208 switch fieldType := structField.Type.(type) { 209 case *ast.FuncType, *ast.InterfaceType, *ast.ChanType: 210 log.Warn(ErrSyllabFieldType, fieldName) 211 case *ast.ArrayType: 212 // Check array is slice? 213 if fieldType.Len == nil { 214 // Slice generator 215 switch sliceType := fieldType.Elt.(type) { 216 case *ast.ArrayType: 217 // Check array is slice? 218 if fieldType.Len == nil { 219 } else { 220 } 221 case *ast.Ident: 222 switch sliceType.Name { 223 case "int", "uint": 224 log.Warn(ErrSyllabFieldType, fieldName) 225 case "bool": 226 if sm.Options.UnSafe { 227 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.UnsafeGetBoolArray(buf, " + sm.getSLIAsString(0) + ")\n") 228 } else { 229 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.GetBoolArray(buf, " + sm.getSLIAsString(0) + ")\n") 230 } 231 sm.Encoder.WriteString(" hsi = syllab.SetBoolArray(buf, " + sm.FRN + fieldName + ", " + sm.getSLIAsString(0) + ", hsi)\n") 232 sm.HeapSize.WriteString(" ln += uint32(len(" + sm.FRN + fieldName + "))\n") 233 case "byte", "uint8": 234 if sm.Options.UnSafe { 235 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.UnsafeGetByteArray(buf, " + sm.getSLIAsString(0) + ")\n") 236 } else { 237 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.GetByteArray(buf, " + sm.getSLIAsString(0) + ")\n") 238 } 239 sm.Encoder.WriteString(" hsi = syllab.SetByteArray(buf, " + sm.FRN + fieldName + ", " + sm.getSLIAsString(0) + ", hsi)\n") 240 sm.HeapSize.WriteString(" ln += uint32(len(" + sm.FRN + fieldName + "))\n") 241 case "int8": 242 if sm.Options.UnSafe { 243 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.UnsafeGetInt8Array(buf, " + sm.getSLIAsString(0) + ")\n") 244 } else { 245 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.GetInt8Array(buf, " + sm.getSLIAsString(0) + ")\n") 246 } 247 sm.Encoder.WriteString(" hsi = syllab.SetInt8Array(buf, " + sm.FRN + fieldName + ", " + sm.getSLIAsString(0) + ", hsi)\n") 248 sm.HeapSize.WriteString(" ln += uint32(len(" + sm.FRN + fieldName + "))\n") 249 case "uint16": 250 if sm.Options.UnSafe { 251 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.UnsafeGetUInt16Array(buf, " + sm.getSLIAsString(0) + ")\n") 252 } else { 253 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.GetUInt16Array(buf, " + sm.getSLIAsString(0) + ")\n") 254 } 255 sm.Encoder.WriteString(" hsi = syllab.SetUInt16Array(buf, " + sm.FRN + fieldName + ", " + sm.getSLIAsString(0) + ", hsi)\n") 256 sm.HeapSize.WriteString(" ln += uint32(len(" + sm.FRN + fieldName + ") * 2)\n") 257 case "int16": 258 if sm.Options.UnSafe { 259 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.UnsafeGetInt16Array(buf, " + sm.getSLIAsString(0) + ")\n") 260 } else { 261 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.GetInt16Array(buf, " + sm.getSLIAsString(0) + ")\n") 262 } 263 sm.Encoder.WriteString(" hsi = syllab.SetInt16Array(buf, " + sm.FRN + fieldName + ", " + sm.getSLIAsString(0) + ", hsi)\n") 264 sm.HeapSize.WriteString(" ln += uint32(len(" + sm.FRN + fieldName + ") * 2)\n") 265 case "uint32": 266 if sm.Options.UnSafe { 267 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.UnsafeGetUInt32Array(buf, " + sm.getSLIAsString(0) + ")\n") 268 } else { 269 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.GetUInt32Array(buf, " + sm.getSLIAsString(0) + ")\n") 270 } 271 sm.Encoder.WriteString(" hsi = syllab.SetUInt32Array(buf, " + sm.FRN + fieldName + ", " + sm.getSLIAsString(0) + ", hsi)\n") 272 sm.HeapSize.WriteString(" ln += uint32(len(" + sm.FRN + fieldName + ") * 4)\n") 273 case "int32": 274 if sm.Options.UnSafe { 275 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.UnsafeGetInt32Array(buf, " + sm.getSLIAsString(0) + ")\n") 276 } else { 277 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.GetInt32Array(buf, " + sm.getSLIAsString(0) + ")\n") 278 } 279 sm.Encoder.WriteString(" hsi = syllab.SetInt32Array(buf, " + sm.FRN + fieldName + ", " + sm.getSLIAsString(0) + ", hsi)\n") 280 sm.HeapSize.WriteString(" ln += uint32(len(" + sm.FRN + fieldName + ") * 4)\n") 281 case "uint64": 282 if sm.Options.UnSafe { 283 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.UnsafeGetUInt64Array(buf, " + sm.getSLIAsString(0) + ")\n") 284 } else { 285 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.GetUInt64Array(buf, " + sm.getSLIAsString(0) + ")\n") 286 } 287 sm.Encoder.WriteString(" hsi = syllab.SetUInt64Array(buf, " + sm.FRN + fieldName + ", " + sm.getSLIAsString(0) + ", hsi)\n") 288 case "int64": 289 if sm.Options.UnSafe { 290 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.UnsafeGetInt64Array(buf, " + sm.getSLIAsString(0) + ")\n") 291 } else { 292 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.GetInt64Array(buf, " + sm.getSLIAsString(0) + ")\n") 293 } 294 sm.Encoder.WriteString(" hsi = syllab.SetInt64Array(buf, " + sm.FRN + fieldName + ", " + sm.getSLIAsString(0) + ", hsi)\n") 295 sm.HeapSize.WriteString(" ln += uint32(len(" + sm.FRN + fieldName + ") * 8)\n") 296 case "string": 297 if sm.Options.UnSafe { 298 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.UnsafeStringArray(buf, " + sm.getSLIAsString(0) + ")\n") 299 } else { 300 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.GetStringArray(buf, " + sm.getSLIAsString(0) + ")\n") 301 } 302 sm.Encoder.WriteString(" hsi = syllab.SetStringArray(buf, " + sm.FRN + fieldName + ", " + sm.getSLIAsString(0) + ", hsi)\n") 303 sm.HeapSize.WriteString(" for i:=0; i<len(" + sm.FRN + fieldName + "); i++ {\n") 304 sm.HeapSize.WriteString(" ln += uint32(len(" + sm.FRN + fieldName + "[i]))\n") 305 sm.HeapSize.WriteString(" }\n") 306 default: 307 // TODO::: get related type by its name as t.Elt.(*ast.Ident).Name 308 // sm.Encoder.WriteString(" syllab.SetUInt32(buf, " + sm.getSLIAsString(0) + ", hsi)\n") 309 // sm.Encoder.WriteString(" syllab.SetUInt32(buf, " + sm.getSLIAsString(4) + ", ln)\n") 310 // sm.Encoder.WriteString(" copy(buf[hsi:], " + sm.FRN + fieldName + ")\n") 311 // if sm.Options.UnSafe { 312 // sm.Decoder.WriteString(" add = syllab.GetUInt32(buf, " + sm.getSLIAsString(0) + ")\n") 313 // sm.Decoder.WriteString(" ln = syllab.GetUInt32(buf, " + sm.getSLIAsString(4) + ")\n") 314 // sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = buf[add : add+ln]\n") 315 // } else { 316 // sm.Decoder.WriteString(" add = syllab.GetUInt32(buf, " + sm.getSLIAsString(0) + ")\n") 317 // sm.Decoder.WriteString(" ln = syllab.GetUInt32(buf, " + sm.getSLIAsString(4) + ")\n") 318 // sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = make([]byte, ln)\n") 319 // sm.Decoder.WriteString(" copy(" + sm.FRN + fieldName + ", buf[add : add+ln])\n") 320 // } 321 } 322 } 323 // In any case we need 8 byte for address and len of array! 324 sm.LSI += 8 325 } else { 326 // Get array len 327 var ln, err = strconv.ParseUint(fieldType.Len.(*ast.BasicLit).Value, 10, 64) 328 if err != nil { 329 return ErrSyllabArrayLen 330 } 331 332 switch arrayType := fieldType.Elt.(type) { 333 case *ast.BasicLit: 334 if arrayType.Kind == token.STRING { 335 // Its common to use const to indicate number of array like in IP type as [16]byte! 336 // TODO::: get related const value by its name as t.Len.(*ast.BasicLit).Value 337 } 338 case *ast.ArrayType: 339 // Check array is slice? 340 if fieldType.Len == nil { 341 } else { 342 } 343 case *ast.Ident: 344 switch arrayType.Name { 345 case "int", "uint": 346 log.Warn(ErrSyllabFieldType, fieldName) 347 case "bool": 348 sm.Encoder.WriteString(" copy(buf[" + sm.getSLIAsString(0) + ":], convert.UnsafeBoolSliceToByteSlice(" + sm.FRN + fieldName + "[:]))\n") 349 sm.Decoder.WriteString(" copy(" + sm.FRN + fieldName + "[:], convert.UnsafeByteSliceToBoolSlice(buf[" + sm.getSLIAsString(0) + ":]))\n") 350 sm.LSI += ln 351 case "byte", "uint8": 352 sm.Encoder.WriteString(" copy(buf[" + sm.getSLIAsString(0) + ":], " + sm.FRN + fieldName + "[:])\n") 353 sm.Decoder.WriteString(" copy(" + sm.FRN + fieldName + "[:], buf[" + sm.getSLIAsString(0) + ":])\n") 354 sm.LSI += ln 355 case "int8": 356 sm.Encoder.WriteString(" copy(buf[" + sm.getSLIAsString(0) + ":], convert.UnsafeInt8SliceToByteSlice(" + sm.FRN + fieldName + "[:]))\n") 357 sm.Decoder.WriteString(" copy(" + sm.FRN + fieldName + "[:], convert.UnsafeByteSliceToInt8Slice(buf[" + sm.getSLIAsString(0) + ":]))\n") 358 sm.LSI += ln 359 case "uint16": 360 sm.Encoder.WriteString(" copy(buf[" + sm.getSLIAsString(0) + ":], convert.UnsafeUInt16SliceToByteSlice(" + sm.FRN + fieldName + "[:]))\n") 361 sm.Decoder.WriteString(" copy(" + sm.FRN + fieldName + "[:], convert.UnsafeByteSliceToUInt16Slice(buf[" + sm.getSLIAsString(0) + ":]))\n") 362 sm.LSI += ln * 2 363 case "int16": 364 sm.Encoder.WriteString(" copy(buf[" + sm.getSLIAsString(0) + ":], convert.UnsafeInt16SliceToByteSlice(" + sm.FRN + fieldName + "[:]))\n") 365 sm.Decoder.WriteString(" copy(" + sm.FRN + fieldName + "[:], convert.UnsafeByteSliceToInt16Slice(buf[" + sm.getSLIAsString(0) + ":]))\n") 366 sm.LSI += ln * 2 367 case "uint32": 368 sm.Encoder.WriteString(" copy(buf[" + sm.getSLIAsString(0) + ":], convert.UnsafeUInt32SliceToByteSlice(" + sm.FRN + fieldName + "[:]))\n") 369 sm.Decoder.WriteString(" copy(" + sm.FRN + fieldName + "[:], convert.UnsafeByteSliceToUInt32Slice(buf[" + sm.getSLIAsString(0) + ":]))\n") 370 sm.LSI += ln * 4 371 case "int32": 372 sm.Encoder.WriteString(" copy(buf[" + sm.getSLIAsString(0) + ":], convert.UnsafeInt32SliceToByteSlice(" + sm.FRN + fieldName + "[:]))\n") 373 sm.Decoder.WriteString(" copy(" + sm.FRN + fieldName + "[:], convert.UnsafeByteSliceToInt32Slice(buf[" + sm.getSLIAsString(0) + ":]))\n") 374 sm.LSI += ln * 4 375 case "uint64": 376 sm.Encoder.WriteString(" copy(buf[" + sm.getSLIAsString(0) + ":], convert.UnsafeUInt64SliceToByteSlice(" + sm.FRN + fieldName + "[:]))\n") 377 sm.Decoder.WriteString(" copy(" + sm.FRN + fieldName + "[:], convert.UnsafeByteSliceToUInt64Slice(buf[" + sm.getSLIAsString(0) + ":]))\n") 378 sm.LSI += ln * 8 379 case "int64": 380 sm.Encoder.WriteString(" copy(buf[" + sm.getSLIAsString(0) + ":], convert.UnsafeInt64SliceToByteSlice(" + sm.FRN + fieldName + "[:]))\n") 381 sm.Decoder.WriteString(" copy(" + sm.FRN + fieldName + "[:], convert.UnsafeByteSliceToInt64Slice(buf[" + sm.getSLIAsString(0) + ":]))\n") 382 sm.LSI += ln * 8 383 case "float32": 384 sm.Encoder.WriteString(" copy(buf[" + sm.getSLIAsString(0) + ":], convert.UnsafeFloat32SliceToByteSlice(" + sm.FRN + fieldName + "[:]))\n") 385 sm.Decoder.WriteString(" copy(" + sm.FRN + fieldName + "[:], convert.UnsafeByteSliceToFloat32Slice(buf[" + sm.getSLIAsString(0) + ":]))\n") 386 sm.LSI += ln * 4 387 case "float64": 388 sm.Encoder.WriteString(" copy(buf[" + sm.getSLIAsString(0) + ":], convert.UnsafeFloat64SliceToByteSlice(" + sm.FRN + fieldName + "[:]))\n") 389 sm.Decoder.WriteString(" copy(" + sm.FRN + fieldName + "[:], convert.UnsafeByteSliceToFloat64Slice(buf[" + sm.getSLIAsString(0) + ":]))\n") 390 sm.LSI += ln * 4 391 case "string": 392 if sm.Options.UnSafe { 393 // sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.UnsafeStringArray(buf, " + sm.getSLIAsString(0) + ")\n") 394 } else { 395 // sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.GetStringArray(buf, " + sm.getSLIAsString(0) + ")\n") 396 } 397 sm.Encoder.WriteString(" hsi = syllab.SetStringArray(buf, " + sm.FRN + fieldName + "[:], " + sm.getSLIAsString(0) + ", hsi)\n") 398 sm.HeapSize.WriteString(" for i:=0; i<" + fieldType.Len.(*ast.BasicLit).Value + "; i++ {\n") 399 sm.HeapSize.WriteString(" ln += len(" + sm.FRN + fieldName + "[i])\n") 400 sm.HeapSize.WriteString(" }\n") 401 default: 402 // TODO::: get related type by its name as fieldType.Elt.(*ast.Ident).Name 403 } 404 } 405 } 406 case *ast.StructType: 407 var tmp = sm.FRN 408 sm.FRN += fieldName + "." 409 sm.RTN = fieldType.Fields.List[0].Names[0].Name 410 // TODO::: add struct itself to sm.Types 411 err = sm.make() 412 sm.FRN = tmp 413 case *ast.MapType: 414 415 case *ast.Ident: 416 switch fieldType.Name { 417 case "int", "uint": 418 log.Warn(ErrSyllabFieldType, fieldName) 419 case "bool": 420 // Inlined by go compiler! So don't respect dev wants not use HelperFuncs 421 sm.Encoder.WriteString(" syllab.SetBool(buf, " + sm.getSLIAsString(0) + ", " + sm.FRN + fieldName + ")\n") 422 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.GetBool(buf, " + sm.getSLIAsString(0) + ")\n") 423 sm.LSI++ 424 case "byte": 425 // Inlined by go compiler! So don't respect dev wants not use HelperFuncs 426 sm.Encoder.WriteString(" syllab.SetByte(buf, " + sm.getSLIAsString(0) + ", " + sm.FRN + fieldName + ")\n") 427 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.GetByte(buf, " + sm.getSLIAsString(0) + ")\n") 428 sm.LSI++ 429 case "int8": 430 // Inlined by go compiler! So don't respect dev wants not use HelperFuncs 431 sm.Encoder.WriteString(" syllab.SetInt8(buf, " + sm.getSLIAsString(0) + ", " + sm.FRN + fieldName + ")\n") 432 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.GetInt8(buf, " + sm.getSLIAsString(0) + ")\n") 433 sm.LSI++ 434 case "uint8": 435 // Inlined by go compiler! So don't respect dev wants not use HelperFuncs 436 sm.Encoder.WriteString(" syllab.SetUInt8(buf, " + sm.getSLIAsString(0) + ", " + sm.FRN + fieldName + ")\n") 437 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.GetUInt8(buf, " + sm.getSLIAsString(0) + ")\n") 438 sm.LSI++ 439 case "int16": 440 // Inlined by go compiler! So don't respect dev wants not use HelperFuncs 441 sm.Encoder.WriteString(" syllab.SetInt16(buf, " + sm.getSLIAsString(0) + ", " + sm.FRN + fieldName + ")\n") 442 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.GetInt16(buf, " + sm.getSLIAsString(0) + ")\n") 443 sm.LSI += 2 444 case "uint16": 445 // Inlined by go compiler! So don't respect dev wants not use HelperFuncs 446 sm.Encoder.WriteString(" syllab.SetUInt16(buf, " + sm.getSLIAsString(0) + ", " + sm.FRN + fieldName + ")\n") 447 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.GetUInt16(buf, " + sm.getSLIAsString(0) + ")\n") 448 sm.LSI += 2 449 case "int32": 450 // Inlined by go compiler! So don't respect dev wants not use HelperFuncs 451 sm.Encoder.WriteString(" syllab.SetInt32(buf, " + sm.getSLIAsString(0) + ", " + sm.FRN + fieldName + ")\n") 452 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.GetInt32(buf, " + sm.getSLIAsString(0) + ")\n") 453 sm.LSI += 4 454 case "uint32": 455 // Inlined by go compiler! So don't respect dev wants not use HelperFuncs 456 sm.Encoder.WriteString(" syllab.SetUInt32(buf, " + sm.getSLIAsString(0) + ", " + sm.FRN + fieldName + ")\n") 457 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.GetUInt32(buf, " + sm.getSLIAsString(0) + ")\n") 458 sm.LSI += 4 459 case "int64": 460 // Inlined by go compiler! So don't respect dev wants not use HelperFuncs 461 sm.Encoder.WriteString(" syllab.SetInt64(buf, " + sm.getSLIAsString(0) + ", " + sm.FRN + fieldName + ")\n") 462 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.GetInt64(buf, " + sm.getSLIAsString(0) + ")\n") 463 sm.LSI += 8 464 case "uint64": 465 // Inlined by go compiler! So don't respect dev wants not use HelperFuncs 466 sm.Encoder.WriteString(" syllab.SetUInt64(buf, " + sm.getSLIAsString(0) + ", " + sm.FRN + fieldName + ")\n") 467 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.GetUInt64(buf, " + sm.getSLIAsString(0) + ")\n") 468 sm.LSI += 8 469 case "float32": 470 // Inlined by go compiler! So don't respect dev wants not use HelperFuncs 471 sm.Encoder.WriteString(" syllab.SetFloat32(buf, " + sm.getSLIAsString(0) + ", " + sm.FRN + fieldName + ")\n") 472 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.GetFloat32(buf, " + sm.getSLIAsString(0) + ")\n") 473 sm.LSI += 4 474 case "float64": 475 // Inlined by go compiler! So don't respect dev wants not use HelperFuncs 476 sm.Encoder.WriteString(" syllab.SetFloat64(buf, " + sm.getSLIAsString(0) + ", " + sm.FRN + fieldName + ")\n") 477 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.GetFloat64(buf, " + sm.getSLIAsString(0) + ")\n") 478 sm.LSI += 8 479 case "string": 480 if sm.Options.UnSafe { 481 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.UnsafeGetString(buf, " + sm.getSLIAsString(0) + ")\n") 482 } else { 483 sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = syllab.GetString(buf, " + sm.getSLIAsString(0) + ")\n") 484 } 485 sm.Encoder.WriteString(" hsi = syllab.SetString(buf, " + sm.FRN + fieldName + ", " + sm.getSLIAsString(0) + ", hsi)\n") 486 sm.HeapSize.WriteString(" ln += uint32(len(" + sm.FRN + fieldName + "))\n") 487 sm.LSI += 8 488 default: 489 // TODO::: below code not work for very simple type e.g. type test uint8 490 sm.Encoder.WriteString(" hsi = " + sm.FRN + fieldName + ".syllabEncoder(buf, " + sm.getSLIAsString(0) + ", hsi)\n") 491 sm.Decoder.WriteString(" " + sm.FRN + fieldName + ".syllabDecoder(buf, " + sm.getSLIAsString(0) + ")\n") 492 493 sm.StackSize.WriteString(" +" + sm.FRN + fieldName + ".syllabStackLen()") 494 sm.HeapSize.WriteString(" ln += " + sm.FRN + fieldName + ".syllabHeapLen()\n") 495 } 496 case *ast.SelectorExpr: 497 sm.Encoder.WriteString(" hsi = " + sm.FRN + fieldName + ".SyllabEncoder(buf, " + sm.getSLIAsString(0) + ", hsi)\n") 498 sm.Decoder.WriteString(" " + sm.FRN + fieldName + ".SyllabDecoder(buf," + sm.getSLIAsString(0) + ")\n") 499 500 sm.StackSize.WriteString(" + " + sm.FRN + fieldName + ".SyllabStackLen()") 501 sm.HeapSize.WriteString(" ln += " + sm.FRN + fieldName + ".SyllabHeapLen()\n") 502 case *ast.BasicLit: 503 // log.Info("BasicLit :", t.Kind) 504 // sm.Encoder.WriteString(" syllab.SetUInt32(buf, " + sm.getSLIAsString(0) + ", hsi)\n") 505 // sm.Encoder.WriteString(" syllab.SetUInt32(buf, " + sm.getSLIAsString(4) + ", ln)\n") 506 // sm.Encoder.WriteString(" copy(buf[hsi:], " + sm.FRN + fieldName + ")\n") 507 // if sm.Options.UnSafe { 508 // sm.Decoder.WriteString(" add = syllab.GetUInt32(buf, " + sm.getSLIAsString(0) + ")\n") 509 // sm.Decoder.WriteString(" ln = syllab.GetUInt32(buf, " + sm.getSLIAsString(4) + ")\n") 510 // sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = convert.UnsafeByteSliceToString(buf[add : add+ln])\n") 511 // } else { 512 // sm.Decoder.WriteString(" add = syllab.GetUInt32(buf, " + sm.getSLIAsString(0) + ")\n") 513 // sm.Decoder.WriteString(" ln = syllab.GetUInt32(buf, " + sm.getSLIAsString(4) + ")\n") 514 // sm.Decoder.WriteString(" " + sm.FRN + fieldName + " = string(buf[add : add+ln])\n") 515 // } 516 } 517 } 518 } 519 } 520 return 521 } 522 523 func (sm *syllabMaker) getSLIAsString(plus uint64) (s string) { 524 // TODO::: Improve below line! 525 s += strconv.FormatUint(sm.LSI+plus, 10) 526 s += sm.StackSize.String() 527 return 528 } 529 530 func (sm *syllabMaker) checkFieldTag(tagValue string) (notInclude bool) { 531 var structFieldTag = reflect.StructTag(tagValue[1 : len(tagValue)-1]) 532 var structFieldTagSyllab = structFieldTag.Get("syllab") 533 if structFieldTagSyllab == "-" { 534 return true 535 } 536 return 537 }