gen.go 83 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801
  1. // Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved.
  2. // Use of this source code is governed by a MIT license found in the LICENSE file.
  3. //go:build codecgen.exec
  4. // +build codecgen.exec
  5. package codec
  6. import (
  7. "bytes"
  8. "encoding/base64"
  9. "errors"
  10. "fmt"
  11. "go/format"
  12. "io"
  13. "io/ioutil"
  14. "math/rand"
  15. "os"
  16. "reflect"
  17. "regexp"
  18. "sort"
  19. "strconv"
  20. "strings"
  21. "sync"
  22. "text/template"
  23. "time"
  24. // "ugorji.net/zz"
  25. "unicode"
  26. "unicode/utf8"
  27. )
  28. // ---------------------------------------------------
  29. // codecgen supports the full cycle of reflection-based codec:
  30. // - RawExt
  31. // - Raw
  32. // - Extensions
  33. // - (Binary|Text|JSON)(Unm|M)arshal
  34. // - generic by-kind
  35. //
  36. // This means that, for dynamic things, we MUST use reflection to at least get the reflect.Type.
  37. // In those areas, we try to only do reflection or interface-conversion when NECESSARY:
  38. // - Extensions, only if Extensions are configured.
  39. //
  40. // However, note following codecgen caveats:
  41. // - Canonical option.
  42. // If Canonical=true, codecgen'ed code will delegate encoding maps to reflection-based code.
  43. // This is due to the runtime work needed to marshal a map in canonical mode.
  44. // - CheckCircularRef option.
  45. // When encoding a struct, a circular reference can lead to a stack overflow.
  46. // If CheckCircularRef=true, codecgen'ed code will delegate encoding structs to reflection-based code.
  47. // - MissingFielder implementation.
  48. // If a type implements MissingFielder, a Selfer is not generated (with a warning message).
  49. // Statically reproducing the runtime work needed to extract the missing fields and marshal them along with the struct fields,
  50. // while handling the Canonical=true special case, was onerous to implement.
  51. //
  52. // During encode/decode, Selfer takes precedence.
  53. // A type implementing Selfer will know how to encode/decode itself statically.
  54. //
  55. // The following field types are supported:
  56. // array: [n]T
  57. // slice: []T
  58. // map: map[K]V
  59. // primitive: [u]int[n], float(32|64), bool, string
  60. // struct
  61. //
  62. // ---------------------------------------------------
  63. // Note that a Selfer cannot call (e|d).(En|De)code on itself,
  64. // as this will cause a circular reference, as (En|De)code will call Selfer methods.
  65. // Any type that implements Selfer must implement completely and not fallback to (En|De)code.
  66. //
  67. // In addition, code in this file manages the generation of fast-path implementations of
  68. // encode/decode of slices/maps of primitive keys/values.
  69. //
  70. // Users MUST re-generate their implementations whenever the code shape changes.
  71. // The generated code will panic if it was generated with a version older than the supporting library.
  72. // ---------------------------------------------------
  73. //
  74. // codec framework is very feature rich.
  75. // When encoding or decoding into an interface, it depends on the runtime type of the interface.
  76. // The type of the interface may be a named type, an extension, etc.
  77. // Consequently, we fallback to runtime codec for encoding/decoding interfaces.
  78. // In addition, we fallback for any value which cannot be guaranteed at runtime.
  79. // This allows us support ANY value, including any named types, specifically those which
  80. // do not implement our interfaces (e.g. Selfer).
  81. //
  82. // This explains some slowness compared to other code generation codecs (e.g. msgp).
  83. // This reduction in speed is only seen when your refers to interfaces,
  84. // e.g. type T struct { A interface{}; B []interface{}; C map[string]interface{} }
  85. //
  86. // codecgen will panic if the file was generated with an old version of the library in use.
  87. //
  88. // Note:
  89. // It was a conscious decision to have gen.go always explicitly call EncodeNil or TryDecodeAsNil.
  90. // This way, there isn't a function call overhead just to see that we should not enter a block of code.
  91. //
  92. // Note:
  93. // codecgen-generated code depends on the variables defined by fast-path.generated.go.
  94. // consequently, you cannot run with tags "codecgen codec.notfastpath".
  95. //
  96. // Note:
  97. // genInternalXXX functions are used for generating fast-path and other internally generated
  98. // files, and not for use in codecgen.
  99. // Size of a struct or value is not portable across machines, especially across 32-bit vs 64-bit
  100. // operating systems. This is due to types like int, uintptr, pointers, (and derived types like slice), etc
  101. // which use the natural word size on those machines, which may be 4 bytes (on 32-bit) or 8 bytes (on 64-bit).
  102. //
  103. // Within decInferLen calls, we may generate an explicit size of the entry.
  104. // We do this because decInferLen values are expected to be approximate,
  105. // and serve as a good hint on the size of the elements or key+value entry.
  106. //
  107. // Since development is done on 64-bit machines, the sizes will be roughly correctly
  108. // on 64-bit OS, and slightly larger than expected on 32-bit OS.
  109. // This is ok.
  110. //
  111. // For reference, look for 'Size' in fast-path.go.tmpl, gen-dec-(array|map).go.tmpl and gen.go (this file).
  112. // GenVersion is the current version of codecgen.
  113. //
  114. // MARKER: Increment this value each time codecgen changes fundamentally.
  115. // Also update codecgen/gen.go (minimumCodecVersion, genVersion, etc).
  116. // Fundamental changes are:
  117. // - helper methods change (signature change, new ones added, some removed, etc)
  118. // - codecgen command line changes
  119. //
  120. // v1: Initial Version
  121. // v2: -
  122. // v3: Changes for Kubernetes:
  123. // changes in signature of some unpublished helper methods and codecgen cmdline arguments.
  124. // v4: Removed separator support from (en|de)cDriver, and refactored codec(gen)
  125. // v5: changes to support faster json decoding. Let encoder/decoder maintain state of collections.
  126. // v6: removed unsafe from gen, and now uses codecgen.exec tag
  127. // v7: -
  128. // v8: current - we now maintain compatibility with old generated code.
  129. // v9: skipped
  130. // v10: modified encDriver and decDriver interfaces.
  131. // v11: remove deprecated methods of encDriver and decDriver.
  132. // v12: removed deprecated methods from genHelper and changed container tracking logic
  133. // v13: 20190603 removed DecodeString - use DecodeStringAsBytes instead
  134. // v14: 20190611 refactored nil handling: TryDecodeAsNil -> selective TryNil, etc
  135. // v15: 20190626 encDriver.EncodeString handles StringToRaw flag inside handle
  136. // v16: 20190629 refactoring for v1.1.6
  137. // v17: 20200911 reduce number of types for which we generate fast path functions (v1.1.8)
  138. // v18: 20201004 changed definition of genHelper...Extension (to take interface{}) and eliminated I2Rtid method
  139. // v19: 20201115 updated codecgen cmdline flags and optimized output
  140. // v20: 20201120 refactored GenHelper to one exported function
  141. // v21: 20210104 refactored generated code to honor ZeroCopy=true for more efficiency
  142. // v22: 20210118 fixed issue in generated code when encoding a type which is also a codec.Selfer
  143. // v23: 20210203 changed slice/map types for which we generate fast-path functions
  144. // v24: 20210226 robust handling for Canonical|CheckCircularRef flags and MissingFielder implementations
  145. // v25: 20210406 pass base reflect.Type to side(En|De)code and (En|De)codeExt calls
  146. const genVersion = 25
  147. const (
  148. genCodecPkg = "codec1978" // MARKER: keep in sync with codecgen/gen.go
  149. genTempVarPfx = "yy"
  150. genTopLevelVarName = "x"
  151. // ignore canBeNil parameter, and always set to true.
  152. // This is because nil can appear anywhere, so we should always check.
  153. genAnythingCanBeNil = true
  154. // if genUseOneFunctionForDecStructMap, make a single codecDecodeSelferFromMap function;
  155. // else make codecDecodeSelferFromMap{LenPrefix,CheckBreak} so that conditionals
  156. // are not executed a lot.
  157. //
  158. // From testing, it didn't make much difference in runtime, so keep as true (one function only)
  159. genUseOneFunctionForDecStructMap = true
  160. // genStructCanonical configures whether we generate 2 paths based on Canonical flag
  161. // when encoding struct fields.
  162. genStructCanonical = false
  163. // genFastpathCanonical configures whether we support Canonical in fast path.
  164. // The savings is not much.
  165. //
  166. // MARKER: This MUST ALWAYS BE TRUE. fast-path.go.tmp doesn't handle it being false.
  167. genFastpathCanonical = true
  168. // genFastpathTrimTypes configures whether we trim uncommon fastpath types.
  169. genFastpathTrimTypes = true
  170. // genDecStructArrayInlineLoopCheck configures whether we create a next function
  171. // for each iteration in the loop and call it, or just inline it.
  172. //
  173. // with inlining, we get better performance but about 10% larger files.
  174. genDecStructArrayInlineLoopCheck = true
  175. )
  176. type genStructMapStyle uint8
  177. type genStringDecAsBytes string
  178. type genStringDecZC string
  179. var genStringDecAsBytesTyp = reflect.TypeOf(genStringDecAsBytes(""))
  180. var genStringDecZCTyp = reflect.TypeOf(genStringDecZC(""))
  181. var genFormats = []string{"Json", "Cbor", "Msgpack", "Binc", "Simple"}
  182. const (
  183. genStructMapStyleConsolidated genStructMapStyle = iota
  184. genStructMapStyleLenPrefix
  185. genStructMapStyleCheckBreak
  186. )
  187. var (
  188. errGenAllTypesSamePkg = errors.New("All types must be in the same package")
  189. errGenExpectArrayOrMap = errors.New("unexpected type - expecting array/map/slice")
  190. errGenUnexpectedTypeFastpath = errors.New("fast-path: unexpected type - requires map or slice")
  191. genBase64enc = base64.NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789__")
  192. genQNameRegex = regexp.MustCompile(`[A-Za-z_.]+`)
  193. )
  194. type genBuf struct {
  195. buf []byte
  196. }
  197. func (x *genBuf) sIf(b bool, s, t string) *genBuf {
  198. if b {
  199. x.buf = append(x.buf, s...)
  200. } else {
  201. x.buf = append(x.buf, t...)
  202. }
  203. return x
  204. }
  205. func (x *genBuf) s(s string) *genBuf { x.buf = append(x.buf, s...); return x }
  206. func (x *genBuf) b(s []byte) *genBuf { x.buf = append(x.buf, s...); return x }
  207. func (x *genBuf) v() string { return string(x.buf) }
  208. func (x *genBuf) f(s string, args ...interface{}) { x.s(fmt.Sprintf(s, args...)) }
  209. func (x *genBuf) reset() {
  210. if x.buf != nil {
  211. x.buf = x.buf[:0]
  212. }
  213. }
  214. // genRunner holds some state used during a Gen run.
  215. type genRunner struct {
  216. w io.Writer // output
  217. c uint64 // counter used for generating varsfx
  218. f uint64 // counter used for saying false
  219. t []reflect.Type // list of types to run selfer on
  220. tc reflect.Type // currently running selfer on this type
  221. te map[uintptr]bool // types for which the encoder has been created
  222. td map[uintptr]bool // types for which the decoder has been created
  223. tz map[uintptr]bool // types for which GenIsZero has been created
  224. cp string // codec import path
  225. im map[string]reflect.Type // imports to add
  226. imn map[string]string // package names of imports to add
  227. imc uint64 // counter for import numbers
  228. is map[reflect.Type]struct{} // types seen during import search
  229. bp string // base PkgPath, for which we are generating for
  230. cpfx string // codec package prefix
  231. ty map[reflect.Type]struct{} // types for which GenIsZero *should* be created
  232. tm map[reflect.Type]struct{} // types for which enc/dec must be generated
  233. ts []reflect.Type // types for which enc/dec must be generated
  234. xs string // top level variable/constant suffix
  235. hn string // fn helper type name
  236. ti *TypeInfos
  237. // rr *rand.Rand // random generator for file-specific types
  238. jsonOnlyWhen, toArrayWhen, omitEmptyWhen *bool
  239. nx bool // no extensions
  240. }
  241. type genIfClause struct {
  242. hasIf bool
  243. }
  244. func (g *genIfClause) end(x *genRunner) {
  245. if g.hasIf {
  246. x.line("}")
  247. }
  248. }
  249. func (g *genIfClause) c(last bool) (v string) {
  250. if last {
  251. if g.hasIf {
  252. v = " } else { "
  253. }
  254. } else if g.hasIf {
  255. v = " } else if "
  256. } else {
  257. v = "if "
  258. g.hasIf = true
  259. }
  260. return
  261. }
  262. // Gen will write a complete go file containing Selfer implementations for each
  263. // type passed. All the types must be in the same package.
  264. //
  265. // Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINUOUSLY WITHOUT NOTICE.
  266. func Gen(w io.Writer, buildTags, pkgName, uid string, noExtensions bool,
  267. jsonOnlyWhen, toArrayWhen, omitEmptyWhen *bool,
  268. ti *TypeInfos, types ...reflect.Type) (warnings []string) {
  269. // All types passed to this method do not have a codec.Selfer method implemented directly.
  270. // codecgen already checks the AST and skips any types that define the codec.Selfer methods.
  271. // Consequently, there's no need to check and trim them if they implement codec.Selfer
  272. if len(types) == 0 {
  273. return
  274. }
  275. x := genRunner{
  276. w: w,
  277. t: types,
  278. te: make(map[uintptr]bool),
  279. td: make(map[uintptr]bool),
  280. tz: make(map[uintptr]bool),
  281. im: make(map[string]reflect.Type),
  282. imn: make(map[string]string),
  283. is: make(map[reflect.Type]struct{}),
  284. tm: make(map[reflect.Type]struct{}),
  285. ty: make(map[reflect.Type]struct{}),
  286. ts: []reflect.Type{},
  287. bp: genImportPath(types[0]),
  288. xs: uid,
  289. ti: ti,
  290. jsonOnlyWhen: jsonOnlyWhen,
  291. toArrayWhen: toArrayWhen,
  292. omitEmptyWhen: omitEmptyWhen,
  293. nx: noExtensions,
  294. }
  295. if x.ti == nil {
  296. x.ti = defTypeInfos
  297. }
  298. if x.xs == "" {
  299. rr := rand.New(rand.NewSource(time.Now().UnixNano()))
  300. x.xs = strconv.FormatInt(rr.Int63n(9999), 10)
  301. }
  302. // gather imports first:
  303. x.cp = genImportPath(reflect.TypeOf(x))
  304. x.imn[x.cp] = genCodecPkg
  305. // iterate, check if all in same package, and remove any missingfielders
  306. for i := 0; i < len(x.t); {
  307. t := x.t[i]
  308. // xdebugf("###########: PkgPath: '%v', Name: '%s'\n", genImportPath(t), t.Name())
  309. if genImportPath(t) != x.bp {
  310. halt.onerror(errGenAllTypesSamePkg)
  311. }
  312. ti1 := x.ti.get(rt2id(t), t)
  313. if ti1.flagMissingFielder || ti1.flagMissingFielderPtr {
  314. // output diagnostic message - that nothing generated for this type
  315. warnings = append(warnings, fmt.Sprintf("type: '%v' not generated; implements codec.MissingFielder", t))
  316. copy(x.t[i:], x.t[i+1:])
  317. x.t = x.t[:len(x.t)-1]
  318. continue
  319. }
  320. x.genRefPkgs(t)
  321. i++
  322. }
  323. x.line("// +build go1.6")
  324. if buildTags != "" {
  325. x.line("// +build " + buildTags)
  326. }
  327. x.line(`
  328. // Code generated by codecgen - DO NOT EDIT.
  329. `)
  330. x.line("package " + pkgName)
  331. x.line("")
  332. x.line("import (")
  333. if x.cp != x.bp {
  334. x.cpfx = genCodecPkg + "."
  335. x.linef("%s \"%s\"", genCodecPkg, x.cp)
  336. }
  337. // use a sorted set of im keys, so that we can get consistent output
  338. imKeys := make([]string, 0, len(x.im))
  339. for k := range x.im {
  340. imKeys = append(imKeys, k)
  341. }
  342. sort.Strings(imKeys)
  343. for _, k := range imKeys { // for k, _ := range x.im {
  344. if k == x.imn[k] {
  345. x.linef("\"%s\"", k)
  346. } else {
  347. x.linef("%s \"%s\"", x.imn[k], k)
  348. }
  349. }
  350. // add required packages
  351. for _, k := range [...]string{"runtime", "errors", "strconv"} { // "reflect", "fmt"
  352. if _, ok := x.im[k]; !ok {
  353. x.line("\"" + k + "\"")
  354. }
  355. }
  356. x.line(")")
  357. x.line("")
  358. x.line("const (")
  359. x.linef("// ----- content types ----")
  360. x.linef("codecSelferCcUTF8%s = %v", x.xs, int64(cUTF8))
  361. x.linef("codecSelferCcRAW%s = %v", x.xs, int64(cRAW))
  362. x.linef("// ----- value types used ----")
  363. for _, vt := range [...]valueType{
  364. valueTypeArray, valueTypeMap, valueTypeString,
  365. valueTypeInt, valueTypeUint, valueTypeFloat,
  366. valueTypeNil,
  367. } {
  368. x.linef("codecSelferValueType%s%s = %v", vt.String(), x.xs, int64(vt))
  369. }
  370. x.linef("codecSelferBitsize%s = uint8(32 << (^uint(0) >> 63))", x.xs)
  371. x.linef("codecSelferDecContainerLenNil%s = %d", x.xs, int64(containerLenNil))
  372. x.line(")")
  373. x.line("var (")
  374. x.line("errCodecSelferOnlyMapOrArrayEncodeToStruct" + x.xs + " = " + "errors.New(`only encoded map or array can be decoded into a struct`)")
  375. x.line(")")
  376. x.line("")
  377. x.hn = "codecSelfer" + x.xs
  378. x.line("type " + x.hn + " struct{}")
  379. x.line("")
  380. x.linef("func %sFalse() bool { return false }", x.hn)
  381. x.linef("func %sTrue() bool { return true }", x.hn)
  382. x.line("")
  383. x.varsfxreset()
  384. x.line("func init() {")
  385. x.linef("if %sGenVersion != %v {", x.cpfx, genVersion)
  386. x.line("_, file, _, _ := runtime.Caller(0)")
  387. x.linef("ver := strconv.FormatInt(int64(%sGenVersion), 10)", x.cpfx)
  388. x.outf(`panic(errors.New("codecgen version mismatch: current: %v, need " + ver + ". Re-generate file: " + file))`, genVersion)
  389. x.linef("}")
  390. if len(imKeys) > 0 {
  391. x.line("if false { // reference the types, but skip this branch at build/run time")
  392. for _, k := range imKeys {
  393. t := x.im[k]
  394. x.linef("var _ %s.%s", x.imn[k], t.Name())
  395. }
  396. x.line("} ") // close if false
  397. }
  398. x.line("}") // close init
  399. x.line("")
  400. // generate rest of type info
  401. for _, t := range x.t {
  402. x.tc = t
  403. x.linef("func (%s) codecSelferViaCodecgen() {}", x.genTypeName(t))
  404. x.selfer(true)
  405. x.selfer(false)
  406. x.tryGenIsZero(t)
  407. }
  408. for _, t := range x.ts {
  409. rtid := rt2id(t)
  410. // generate enc functions for all these slice/map types.
  411. x.varsfxreset()
  412. x.linef("func (x %s) enc%s(v %s%s, e *%sEncoder) {", x.hn, x.genMethodNameT(t), x.arr2str(t, "*"), x.genTypeName(t), x.cpfx)
  413. x.genRequiredMethodVars(true)
  414. switch t.Kind() {
  415. case reflect.Array, reflect.Slice, reflect.Chan:
  416. x.encListFallback("v", t)
  417. case reflect.Map:
  418. x.encMapFallback("v", t)
  419. default:
  420. halt.onerror(errGenExpectArrayOrMap)
  421. }
  422. x.line("}")
  423. x.line("")
  424. // generate dec functions for all these slice/map types.
  425. x.varsfxreset()
  426. x.linef("func (x %s) dec%s(v *%s, d *%sDecoder) {", x.hn, x.genMethodNameT(t), x.genTypeName(t), x.cpfx)
  427. x.genRequiredMethodVars(false)
  428. switch t.Kind() {
  429. case reflect.Array, reflect.Slice, reflect.Chan:
  430. x.decListFallback("v", rtid, t)
  431. case reflect.Map:
  432. x.decMapFallback("v", rtid, t)
  433. default:
  434. halt.onerror(errGenExpectArrayOrMap)
  435. }
  436. x.line("}")
  437. x.line("")
  438. }
  439. for t := range x.ty {
  440. x.tryGenIsZero(t)
  441. x.line("")
  442. }
  443. x.line("")
  444. return
  445. }
  446. func (x *genRunner) checkForSelfer(t reflect.Type, varname string) bool {
  447. // return varname != genTopLevelVarName && t != x.tc
  448. // the only time we checkForSelfer is if we are not at the TOP of the generated code.
  449. return varname != genTopLevelVarName
  450. }
  451. func (x *genRunner) arr2str(t reflect.Type, s string) string {
  452. if t.Kind() == reflect.Array {
  453. return s
  454. }
  455. return ""
  456. }
  457. func (x *genRunner) genRequiredMethodVars(encode bool) {
  458. x.line("var h " + x.hn)
  459. if encode {
  460. x.line("z, r := " + x.cpfx + "GenHelper().Encoder(e)")
  461. } else {
  462. x.line("z, r := " + x.cpfx + "GenHelper().Decoder(d)")
  463. }
  464. x.line("_, _, _ = h, z, r")
  465. }
  466. func (x *genRunner) genRefPkgs(t reflect.Type) {
  467. if _, ok := x.is[t]; ok {
  468. return
  469. }
  470. x.is[t] = struct{}{}
  471. tpkg, tname := genImportPath(t), t.Name()
  472. if tpkg != "" && tpkg != x.bp && tpkg != x.cp && tname != "" && tname[0] >= 'A' && tname[0] <= 'Z' {
  473. if _, ok := x.im[tpkg]; !ok {
  474. x.im[tpkg] = t
  475. if idx := strings.LastIndex(tpkg, "/"); idx < 0 {
  476. x.imn[tpkg] = tpkg
  477. } else {
  478. x.imc++
  479. x.imn[tpkg] = "pkg" + strconv.FormatUint(x.imc, 10) + "_" + genGoIdentifier(tpkg[idx+1:], false)
  480. }
  481. }
  482. }
  483. switch t.Kind() {
  484. case reflect.Array, reflect.Slice, reflect.Ptr, reflect.Chan:
  485. x.genRefPkgs(t.Elem())
  486. case reflect.Map:
  487. x.genRefPkgs(t.Elem())
  488. x.genRefPkgs(t.Key())
  489. case reflect.Struct:
  490. for i := 0; i < t.NumField(); i++ {
  491. if fname := t.Field(i).Name; fname != "" && fname[0] >= 'A' && fname[0] <= 'Z' {
  492. x.genRefPkgs(t.Field(i).Type)
  493. }
  494. }
  495. }
  496. }
  497. // sayFalse will either say "false" or use a function call that returns false.
  498. func (x *genRunner) sayFalse() string {
  499. x.f++
  500. if x.f%2 == 0 {
  501. return x.hn + "False()"
  502. }
  503. return "false"
  504. }
  505. // sayFalse will either say "true" or use a function call that returns true.
  506. func (x *genRunner) sayTrue() string {
  507. x.f++
  508. if x.f%2 == 0 {
  509. return x.hn + "True()"
  510. }
  511. return "true"
  512. }
  513. func (x *genRunner) varsfx() string {
  514. x.c++
  515. return strconv.FormatUint(x.c, 10)
  516. }
  517. func (x *genRunner) varsfxreset() {
  518. x.c = 0
  519. }
  520. func (x *genRunner) out(s string) {
  521. _, err := io.WriteString(x.w, s)
  522. genCheckErr(err)
  523. }
  524. func (x *genRunner) outf(s string, params ...interface{}) {
  525. _, err := fmt.Fprintf(x.w, s, params...)
  526. genCheckErr(err)
  527. }
  528. func (x *genRunner) line(s string) {
  529. x.out(s)
  530. if len(s) == 0 || s[len(s)-1] != '\n' {
  531. x.out("\n")
  532. }
  533. }
  534. func (x *genRunner) lineIf(s string) {
  535. if s != "" {
  536. x.line(s)
  537. }
  538. }
  539. func (x *genRunner) linef(s string, params ...interface{}) {
  540. x.outf(s, params...)
  541. if len(s) == 0 || s[len(s)-1] != '\n' {
  542. x.out("\n")
  543. }
  544. }
  545. func (x *genRunner) genTypeName(t reflect.Type) (n string) {
  546. // if the type has a PkgPath, which doesn't match the current package,
  547. // then include it.
  548. // We cannot depend on t.String() because it includes current package,
  549. // or t.PkgPath because it includes full import path,
  550. //
  551. var ptrPfx string
  552. for t.Kind() == reflect.Ptr {
  553. ptrPfx += "*"
  554. t = t.Elem()
  555. }
  556. if tn := t.Name(); tn != "" {
  557. return ptrPfx + x.genTypeNamePrim(t)
  558. }
  559. switch t.Kind() {
  560. case reflect.Map:
  561. return ptrPfx + "map[" + x.genTypeName(t.Key()) + "]" + x.genTypeName(t.Elem())
  562. case reflect.Slice:
  563. return ptrPfx + "[]" + x.genTypeName(t.Elem())
  564. case reflect.Array:
  565. return ptrPfx + "[" + strconv.FormatInt(int64(t.Len()), 10) + "]" + x.genTypeName(t.Elem())
  566. case reflect.Chan:
  567. return ptrPfx + t.ChanDir().String() + " " + x.genTypeName(t.Elem())
  568. default:
  569. if t == intfTyp {
  570. return ptrPfx + "interface{}"
  571. } else {
  572. return ptrPfx + x.genTypeNamePrim(t)
  573. }
  574. }
  575. }
  576. func (x *genRunner) genTypeNamePrim(t reflect.Type) (n string) {
  577. if t.Name() == "" {
  578. return t.String()
  579. } else if genImportPath(t) == "" || genImportPath(t) == genImportPath(x.tc) {
  580. return t.Name()
  581. } else {
  582. return x.imn[genImportPath(t)] + "." + t.Name()
  583. // return t.String() // best way to get the package name inclusive
  584. }
  585. }
  586. func (x *genRunner) genZeroValueR(t reflect.Type) string {
  587. // if t is a named type, w
  588. switch t.Kind() {
  589. case reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func,
  590. reflect.Slice, reflect.Map, reflect.Invalid:
  591. return "nil"
  592. case reflect.Bool:
  593. return "false"
  594. case reflect.String:
  595. return `""`
  596. case reflect.Struct, reflect.Array:
  597. return x.genTypeName(t) + "{}"
  598. default: // all numbers
  599. return "0"
  600. }
  601. }
  602. func (x *genRunner) genMethodNameT(t reflect.Type) (s string) {
  603. return genMethodNameT(t, x.tc)
  604. }
  605. func (x *genRunner) tryGenIsZero(t reflect.Type) (done bool) {
  606. if t.Kind() != reflect.Struct || t.Implements(isCodecEmptyerTyp) {
  607. return
  608. }
  609. rtid := rt2id(t)
  610. if _, ok := x.tz[rtid]; ok {
  611. delete(x.ty, t)
  612. return
  613. }
  614. x.tz[rtid] = true
  615. delete(x.ty, t)
  616. ti := x.ti.get(rtid, t)
  617. tisfi := ti.sfi.source() // always use sequence from file. decStruct expects same thing.
  618. varname := genTopLevelVarName
  619. x.linef("func (%s *%s) IsCodecEmpty() bool {", varname, x.genTypeName(t))
  620. anonSeen := make(map[reflect.Type]bool)
  621. var omitline genBuf
  622. for _, si := range tisfi {
  623. if si.path.parent != nil {
  624. root := si.path.root()
  625. if anonSeen[root.typ] {
  626. continue
  627. }
  628. anonSeen[root.typ] = true
  629. }
  630. t2 := genOmitEmptyLinePreChecks(varname, t, si, &omitline, true)
  631. // if Ptr, we already checked if nil above
  632. if t2.Type.Kind() != reflect.Ptr {
  633. x.doEncOmitEmptyLine(t2, varname, &omitline)
  634. omitline.s(" || ")
  635. }
  636. }
  637. omitline.s(" false")
  638. x.linef("return !(%s)", omitline.v())
  639. x.line("}")
  640. x.line("")
  641. return true
  642. }
  643. func (x *genRunner) selfer(encode bool) {
  644. t := x.tc
  645. // ti := x.ti.get(rt2id(t), t)
  646. t0 := t
  647. // always make decode use a pointer receiver,
  648. // and structs/arrays always use a ptr receiver (encode|decode)
  649. isptr := !encode || t.Kind() == reflect.Array || (t.Kind() == reflect.Struct && t != timeTyp)
  650. x.varsfxreset()
  651. fnSigPfx := "func (" + genTopLevelVarName + " "
  652. if isptr {
  653. fnSigPfx += "*"
  654. }
  655. fnSigPfx += x.genTypeName(t)
  656. x.out(fnSigPfx)
  657. if isptr {
  658. t = reflect.PtrTo(t)
  659. }
  660. if encode {
  661. x.line(") CodecEncodeSelf(e *" + x.cpfx + "Encoder) {")
  662. x.genRequiredMethodVars(true)
  663. if t0.Kind() == reflect.Struct {
  664. x.linef("if z.EncBasicHandle().CheckCircularRef { z.EncEncode(%s); return }", genTopLevelVarName)
  665. }
  666. x.encVar(genTopLevelVarName, t)
  667. } else {
  668. x.line(") CodecDecodeSelf(d *" + x.cpfx + "Decoder) {")
  669. x.genRequiredMethodVars(false)
  670. // do not use decVar, as there is no need to check TryDecodeAsNil
  671. // or way to elegantly handle that, and also setting it to a
  672. // non-nil value doesn't affect the pointer passed.
  673. // x.decVar(genTopLevelVarName, t, false)
  674. x.dec(genTopLevelVarName, t0, true)
  675. }
  676. x.line("}")
  677. x.line("")
  678. if encode || t0.Kind() != reflect.Struct {
  679. return
  680. }
  681. // write is containerMap
  682. if genUseOneFunctionForDecStructMap {
  683. x.out(fnSigPfx)
  684. x.line(") codecDecodeSelfFromMap(l int, d *" + x.cpfx + "Decoder) {")
  685. x.genRequiredMethodVars(false)
  686. x.decStructMap(genTopLevelVarName, "l", rt2id(t0), t0, genStructMapStyleConsolidated)
  687. x.line("}")
  688. x.line("")
  689. } else {
  690. x.out(fnSigPfx)
  691. x.line(") codecDecodeSelfFromMapLenPrefix(l int, d *" + x.cpfx + "Decoder) {")
  692. x.genRequiredMethodVars(false)
  693. x.decStructMap(genTopLevelVarName, "l", rt2id(t0), t0, genStructMapStyleLenPrefix)
  694. x.line("}")
  695. x.line("")
  696. x.out(fnSigPfx)
  697. x.line(") codecDecodeSelfFromMapCheckBreak(l int, d *" + x.cpfx + "Decoder) {")
  698. x.genRequiredMethodVars(false)
  699. x.decStructMap(genTopLevelVarName, "l", rt2id(t0), t0, genStructMapStyleCheckBreak)
  700. x.line("}")
  701. x.line("")
  702. }
  703. // write containerArray
  704. x.out(fnSigPfx)
  705. x.line(") codecDecodeSelfFromArray(l int, d *" + x.cpfx + "Decoder) {")
  706. x.genRequiredMethodVars(false)
  707. x.decStructArray(genTopLevelVarName, "l", "return", rt2id(t0), t0)
  708. x.line("}")
  709. x.line("")
  710. }
  711. // used for chan, array, slice, map
  712. func (x *genRunner) xtraSM(varname string, t reflect.Type, ti *typeInfo, encode, isptr bool) {
  713. var ptrPfx, addrPfx string
  714. if isptr {
  715. ptrPfx = "*"
  716. } else {
  717. addrPfx = "&"
  718. }
  719. if encode {
  720. x.linef("h.enc%s((%s%s)(%s), e)", x.genMethodNameT(t), ptrPfx, x.genTypeName(t), varname)
  721. } else {
  722. x.linef("h.dec%s((*%s)(%s%s), d)", x.genMethodNameT(t), x.genTypeName(t), addrPfx, varname)
  723. }
  724. x.registerXtraT(t, ti)
  725. }
  726. func (x *genRunner) registerXtraT(t reflect.Type, ti *typeInfo) {
  727. // recursively register the types
  728. tk := t.Kind()
  729. if tk == reflect.Ptr {
  730. x.registerXtraT(t.Elem(), nil)
  731. return
  732. }
  733. if _, ok := x.tm[t]; ok {
  734. return
  735. }
  736. switch tk {
  737. case reflect.Chan, reflect.Slice, reflect.Array, reflect.Map:
  738. default:
  739. return
  740. }
  741. // only register the type if it will not default to a fast-path
  742. if ti == nil {
  743. ti = x.ti.get(rt2id(t), t)
  744. }
  745. if _, rtidu := genFastpathUnderlying(t, ti.rtid, ti); fastpathAvIndex(rtidu) != -1 {
  746. return
  747. }
  748. x.tm[t] = struct{}{}
  749. x.ts = append(x.ts, t)
  750. // check if this refers to any xtra types eg. a slice of array: add the array
  751. x.registerXtraT(t.Elem(), nil)
  752. if tk == reflect.Map {
  753. x.registerXtraT(t.Key(), nil)
  754. }
  755. }
  756. // encVar will encode a variable.
  757. // The parameter, t, is the reflect.Type of the variable itself
  758. func (x *genRunner) encVar(varname string, t reflect.Type) {
  759. var checkNil bool
  760. // case reflect.Ptr, reflect.Interface, reflect.Slice, reflect.Map, reflect.Chan:
  761. // do not include checkNil for slice and maps, as we already checkNil below it
  762. switch t.Kind() {
  763. case reflect.Ptr, reflect.Interface, reflect.Chan:
  764. checkNil = true
  765. }
  766. x.encVarChkNil(varname, t, checkNil)
  767. }
  768. func (x *genRunner) encVarChkNil(varname string, t reflect.Type, checkNil bool) {
  769. if checkNil {
  770. x.linef("if %s == nil { r.EncodeNil() } else {", varname)
  771. }
  772. switch t.Kind() {
  773. case reflect.Ptr:
  774. telem := t.Elem()
  775. tek := telem.Kind()
  776. if tek == reflect.Array || (tek == reflect.Struct && telem != timeTyp) {
  777. x.enc(varname, genNonPtr(t), true)
  778. break
  779. }
  780. i := x.varsfx()
  781. x.line(genTempVarPfx + i + " := *" + varname)
  782. x.enc(genTempVarPfx+i, genNonPtr(t), false)
  783. case reflect.Struct, reflect.Array:
  784. if t == timeTyp {
  785. x.enc(varname, t, false)
  786. break
  787. }
  788. i := x.varsfx()
  789. x.line(genTempVarPfx + i + " := &" + varname)
  790. x.enc(genTempVarPfx+i, t, true)
  791. default:
  792. x.enc(varname, t, false)
  793. }
  794. if checkNil {
  795. x.line("}")
  796. }
  797. }
  798. // enc will encode a variable (varname) of type t, where t represents T.
  799. // if t is !time.Time and t is of kind reflect.Struct or reflect.Array, varname is of type *T
  800. // (to prevent copying),
  801. // else t is of type T
  802. func (x *genRunner) enc(varname string, t reflect.Type, isptr bool) {
  803. rtid := rt2id(t)
  804. ti2 := x.ti.get(rtid, t)
  805. // We call CodecEncodeSelf if one of the following are honored:
  806. // - the type already implements Selfer, call that
  807. // - the type has a Selfer implementation just created, use that
  808. // - the type is in the list of the ones we will generate for, but it is not currently being generated
  809. mi := x.varsfx()
  810. // tptr := reflect.PtrTo(t)
  811. // tk := t.Kind()
  812. // check if
  813. // - type is time.Time, RawExt, Raw
  814. // - the type implements (Text|JSON|Binary)(Unm|M)arshal
  815. var hasIf genIfClause
  816. defer hasIf.end(x) // end if block (if necessary)
  817. var ptrPfx, addrPfx string
  818. if isptr {
  819. ptrPfx = "*"
  820. } else {
  821. addrPfx = "&"
  822. }
  823. if t == timeTyp {
  824. x.linef("%s z.EncBasicHandle().TimeBuiltin() { r.EncodeTime(%s%s)", hasIf.c(false), ptrPfx, varname)
  825. // return
  826. }
  827. if t == rawTyp {
  828. x.linef("%s z.EncRaw(%s%s)", hasIf.c(true), ptrPfx, varname)
  829. return
  830. }
  831. if t == rawExtTyp {
  832. x.linef("%s r.EncodeRawExt(%s%s)", hasIf.c(true), addrPfx, varname)
  833. return
  834. }
  835. // only check for extensions if extensions are configured,
  836. // and the type is named, and has a packagePath,
  837. // and this is not the CodecEncodeSelf or CodecDecodeSelf method (i.e. it is not a Selfer)
  838. if !x.nx && varname != genTopLevelVarName && t != genStringDecAsBytesTyp &&
  839. t != genStringDecZCTyp && genImportPath(t) != "" && t.Name() != "" {
  840. yy := fmt.Sprintf("%sxt%s", genTempVarPfx, mi)
  841. x.linef("%s %s := z.Extension(%s); %s != nil { z.EncExtension(%s, %s) ",
  842. hasIf.c(false), yy, varname, yy, varname, yy)
  843. }
  844. if x.checkForSelfer(t, varname) {
  845. if ti2.flagSelfer {
  846. x.linef("%s %s.CodecEncodeSelf(e)", hasIf.c(true), varname)
  847. return
  848. } else if ti2.flagSelferPtr {
  849. x.linef("%s %ssf%s := &%s", hasIf.c(true), genTempVarPfx, mi, varname)
  850. x.linef("%ssf%s.CodecEncodeSelf(e)", genTempVarPfx, mi)
  851. return
  852. }
  853. if _, ok := x.te[rtid]; ok {
  854. x.linef("%s %s.CodecEncodeSelf(e)", hasIf.c(true), varname)
  855. return
  856. }
  857. }
  858. inlist := false
  859. for _, t0 := range x.t {
  860. if t == t0 {
  861. inlist = true
  862. if x.checkForSelfer(t, varname) {
  863. x.linef("%s %s.CodecEncodeSelf(e)", hasIf.c(true), varname)
  864. return
  865. }
  866. break
  867. }
  868. }
  869. var rtidAdded bool
  870. if t == x.tc {
  871. x.te[rtid] = true
  872. rtidAdded = true
  873. }
  874. if ti2.flagBinaryMarshaler {
  875. x.linef("%s z.EncBinary() { z.EncBinaryMarshal(%s%v) ", hasIf.c(false), ptrPfx, varname)
  876. } else if ti2.flagBinaryMarshalerPtr {
  877. x.linef("%s z.EncBinary() { z.EncBinaryMarshal(%s%v) ", hasIf.c(false), addrPfx, varname)
  878. }
  879. if ti2.flagJsonMarshaler {
  880. x.linef("%s !z.EncBinary() && z.IsJSONHandle() { z.EncJSONMarshal(%s%v) ", hasIf.c(false), ptrPfx, varname)
  881. } else if ti2.flagJsonMarshalerPtr {
  882. x.linef("%s !z.EncBinary() && z.IsJSONHandle() { z.EncJSONMarshal(%s%v) ", hasIf.c(false), addrPfx, varname)
  883. } else if ti2.flagTextMarshaler {
  884. x.linef("%s !z.EncBinary() { z.EncTextMarshal(%s%v) ", hasIf.c(false), ptrPfx, varname)
  885. } else if ti2.flagTextMarshalerPtr {
  886. x.linef("%s !z.EncBinary() { z.EncTextMarshal(%s%v) ", hasIf.c(false), addrPfx, varname)
  887. }
  888. x.lineIf(hasIf.c(true))
  889. switch t.Kind() {
  890. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  891. x.line("r.EncodeInt(int64(" + varname + "))")
  892. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  893. x.line("r.EncodeUint(uint64(" + varname + "))")
  894. case reflect.Float32:
  895. x.line("r.EncodeFloat32(float32(" + varname + "))")
  896. case reflect.Float64:
  897. x.line("r.EncodeFloat64(float64(" + varname + "))")
  898. case reflect.Complex64:
  899. x.linef("z.EncEncodeComplex64(complex64(%s))", varname)
  900. case reflect.Complex128:
  901. x.linef("z.EncEncodeComplex128(complex128(%s))", varname)
  902. case reflect.Bool:
  903. x.line("r.EncodeBool(bool(" + varname + "))")
  904. case reflect.String:
  905. x.linef("r.EncodeString(string(%s))", varname)
  906. case reflect.Chan:
  907. x.xtraSM(varname, t, ti2, true, false)
  908. // x.encListFallback(varname, rtid, t)
  909. case reflect.Array:
  910. _, rtidu := genFastpathUnderlying(t, rtid, ti2)
  911. if fastpathAvIndex(rtidu) != -1 {
  912. g := x.newFastpathGenV(ti2.key)
  913. x.linef("z.F.%sV((%s)(%s[:]), e)", g.MethodNamePfx("Enc", false), x.genTypeName(ti2.key), varname)
  914. } else {
  915. x.xtraSM(varname, t, ti2, true, true)
  916. }
  917. case reflect.Slice:
  918. // if nil, call dedicated function
  919. // if a []byte, call dedicated function
  920. // if a known fastpath slice, call dedicated function
  921. // else write encode function in-line.
  922. // - if elements are primitives or Selfers, call dedicated function on each member.
  923. // - else call Encoder.encode(XXX) on it.
  924. x.linef("if %s == nil { r.EncodeNil() } else {", varname)
  925. if rtid == uint8SliceTypId {
  926. x.line("r.EncodeStringBytesRaw([]byte(" + varname + "))")
  927. } else {
  928. tu, rtidu := genFastpathUnderlying(t, rtid, ti2)
  929. if fastpathAvIndex(rtidu) != -1 {
  930. g := x.newFastpathGenV(tu)
  931. if rtid == rtidu {
  932. x.linef("z.F.%sV(%s, e)", g.MethodNamePfx("Enc", false), varname)
  933. } else {
  934. x.linef("z.F.%sV((%s)(%s), e)", g.MethodNamePfx("Enc", false), x.genTypeName(tu), varname)
  935. }
  936. } else {
  937. x.xtraSM(varname, t, ti2, true, false)
  938. }
  939. }
  940. x.linef("} // end block: if %s slice == nil", varname)
  941. case reflect.Map:
  942. // if nil, call dedicated function
  943. // if a known fastpath map, call dedicated function
  944. // else write encode function in-line.
  945. // - if elements are primitives or Selfers, call dedicated function on each member.
  946. // - else call Encoder.encode(XXX) on it.
  947. x.linef("if %s == nil { r.EncodeNil() } else {", varname)
  948. tu, rtidu := genFastpathUnderlying(t, rtid, ti2)
  949. if fastpathAvIndex(rtidu) != -1 {
  950. g := x.newFastpathGenV(tu)
  951. if rtid == rtidu {
  952. x.linef("z.F.%sV(%s, e)", g.MethodNamePfx("Enc", false), varname)
  953. } else {
  954. x.linef("z.F.%sV((%s)(%s), e)", g.MethodNamePfx("Enc", false), x.genTypeName(tu), varname)
  955. }
  956. } else {
  957. x.xtraSM(varname, t, ti2, true, false)
  958. }
  959. x.linef("} // end block: if %s map == nil", varname)
  960. case reflect.Struct:
  961. if !inlist {
  962. delete(x.te, rtid)
  963. x.line("z.EncFallback(" + varname + ")")
  964. break
  965. }
  966. x.encStruct(varname, rtid, t)
  967. default:
  968. if rtidAdded {
  969. delete(x.te, rtid)
  970. }
  971. x.line("z.EncFallback(" + varname + ")")
  972. }
  973. }
  974. func (x *genRunner) encZero(t reflect.Type) {
  975. switch t.Kind() {
  976. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  977. x.line("r.EncodeInt(0)")
  978. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  979. x.line("r.EncodeUint(0)")
  980. case reflect.Float32:
  981. x.line("r.EncodeFloat32(0)")
  982. case reflect.Float64:
  983. x.line("r.EncodeFloat64(0)")
  984. case reflect.Complex64:
  985. x.line("z.EncEncodeComplex64(0)")
  986. case reflect.Complex128:
  987. x.line("z.EncEncodeComplex128(0)")
  988. case reflect.Bool:
  989. x.line("r.EncodeBool(false)")
  990. case reflect.String:
  991. x.linef(`r.EncodeString("")`)
  992. default:
  993. x.line("r.EncodeNil()")
  994. }
  995. }
  996. func genOmitEmptyLinePreChecks(varname string, t reflect.Type, si *structFieldInfo, omitline *genBuf, oneLevel bool) (t2 reflect.StructField) {
  997. // xdebug2f("calling genOmitEmptyLinePreChecks on: %v", t)
  998. t2typ := t
  999. varname3 := varname
  1000. // go through the loop, record the t2 field explicitly,
  1001. // and gather the omit line if embedded in pointers.
  1002. fullpath := si.path.fullpath()
  1003. for i, path := range fullpath {
  1004. for t2typ.Kind() == reflect.Ptr {
  1005. t2typ = t2typ.Elem()
  1006. }
  1007. t2 = t2typ.Field(int(path.index))
  1008. t2typ = t2.Type
  1009. varname3 = varname3 + "." + t2.Name
  1010. // do not include actual field in the omit line.
  1011. // that is done subsequently (right after - below).
  1012. if i+1 < len(fullpath) && t2typ.Kind() == reflect.Ptr {
  1013. omitline.s(varname3).s(" != nil && ")
  1014. }
  1015. if oneLevel {
  1016. break
  1017. }
  1018. }
  1019. return
  1020. }
  1021. func (x *genRunner) doEncOmitEmptyLine(t2 reflect.StructField, varname string, buf *genBuf) {
  1022. x.f = 0
  1023. x.encOmitEmptyLine(t2, varname, buf)
  1024. }
  1025. func (x *genRunner) encOmitEmptyLine(t2 reflect.StructField, varname string, buf *genBuf) {
  1026. // xdebugf("calling encOmitEmptyLine on: %v", t2.Type)
  1027. // smartly check omitEmpty on a struct type, as it may contain uncomparable map/slice/etc.
  1028. // also, for maps/slices/arrays, check if len ! 0 (not if == zero value)
  1029. varname2 := varname + "." + t2.Name
  1030. switch t2.Type.Kind() {
  1031. case reflect.Struct:
  1032. rtid2 := rt2id(t2.Type)
  1033. ti2 := x.ti.get(rtid2, t2.Type)
  1034. // xdebugf(">>>> structfield: omitempty: type: %s, field: %s\n", t2.Type.Name(), t2.Name)
  1035. if ti2.rtid == timeTypId {
  1036. buf.s("!(").s(varname2).s(".IsZero())")
  1037. break
  1038. }
  1039. if ti2.flagIsZeroerPtr || ti2.flagIsZeroer {
  1040. buf.s("!(").s(varname2).s(".IsZero())")
  1041. break
  1042. }
  1043. if t2.Type.Implements(isCodecEmptyerTyp) {
  1044. buf.s("!(").s(varname2).s(".IsCodecEmpty())")
  1045. break
  1046. }
  1047. _, ok := x.tz[rtid2]
  1048. if ok {
  1049. buf.s("!(").s(varname2).s(".IsCodecEmpty())")
  1050. break
  1051. }
  1052. // if we *should* create a IsCodecEmpty for it, but haven't yet, add it here
  1053. // _, ok = x.ty[rtid2]
  1054. if genImportPath(t2.Type) == x.bp {
  1055. x.ty[t2.Type] = struct{}{}
  1056. buf.s("!(").s(varname2).s(".IsCodecEmpty())")
  1057. break
  1058. }
  1059. if ti2.flagComparable {
  1060. buf.s(varname2).s(" != ").s(x.genZeroValueR(t2.Type))
  1061. break
  1062. }
  1063. // fmt.Printf("???? !!!! We shouldn't get to this point !!!! ???? - for type: %v\n", t2.Type)
  1064. // buf.s("(")
  1065. buf.s(x.sayFalse()) // buf.s("false")
  1066. for i, n := 0, t2.Type.NumField(); i < n; i++ {
  1067. f := t2.Type.Field(i)
  1068. if f.PkgPath != "" { // unexported
  1069. continue
  1070. }
  1071. buf.s(" || ")
  1072. x.encOmitEmptyLine(f, varname2, buf)
  1073. }
  1074. //buf.s(")")
  1075. case reflect.Bool:
  1076. buf.s("bool(").s(varname2).s(")")
  1077. case reflect.Map, reflect.Slice, reflect.Array, reflect.Chan:
  1078. buf.s("len(").s(varname2).s(") != 0")
  1079. default:
  1080. buf.s(varname2).s(" != ").s(x.genZeroValueR(t2.Type))
  1081. }
  1082. }
  1083. func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) {
  1084. // Use knowledge from structfieldinfo (mbs, encodable fields. Ignore omitempty. )
  1085. // replicate code in kStruct i.e. for each field, deref type to non-pointer, and call x.enc on it
  1086. // if t === type currently running selfer on, do for all
  1087. ti := x.ti.get(rtid, t)
  1088. i := x.varsfx()
  1089. // sepVarname := genTempVarPfx + "sep" + i
  1090. numfieldsvar := genTempVarPfx + "q" + i
  1091. ti2arrayvar := genTempVarPfx + "r" + i
  1092. struct2arrvar := genTempVarPfx + "2arr" + i
  1093. tisfi := ti.sfi.source() // always use sequence from file. decStruct expects same thing.
  1094. type genFQN struct {
  1095. i string
  1096. fqname string
  1097. nilLine genBuf
  1098. nilVar string
  1099. canNil bool
  1100. sf reflect.StructField
  1101. }
  1102. genFQNs := make([]genFQN, len(tisfi))
  1103. for j, si := range tisfi {
  1104. q := &genFQNs[j]
  1105. q.i = x.varsfx()
  1106. q.nilVar = genTempVarPfx + "n" + q.i
  1107. q.canNil = false
  1108. q.fqname = varname
  1109. {
  1110. t2typ := t
  1111. fullpath := si.path.fullpath()
  1112. for _, path := range fullpath {
  1113. for t2typ.Kind() == reflect.Ptr {
  1114. t2typ = t2typ.Elem()
  1115. }
  1116. q.sf = t2typ.Field(int(path.index))
  1117. t2typ = q.sf.Type
  1118. q.fqname += "." + q.sf.Name
  1119. if t2typ.Kind() == reflect.Ptr {
  1120. if !q.canNil {
  1121. q.nilLine.f("%s == nil", q.fqname)
  1122. q.canNil = true
  1123. } else {
  1124. q.nilLine.f(" || %s == nil", q.fqname)
  1125. }
  1126. }
  1127. }
  1128. }
  1129. }
  1130. // x.line(sepVarname + " := !z.EncBinary()")
  1131. x.linef("%s := z.EncBasicHandle().StructToArray", struct2arrvar)
  1132. // x.linef("_, _ = %s, %s", sepVarname, struct2arrvar)
  1133. x.linef("_ = %s", struct2arrvar)
  1134. x.linef("const %s bool = %v // struct tag has 'toArray'", ti2arrayvar, ti.toArray)
  1135. for j := range genFQNs {
  1136. q := &genFQNs[j]
  1137. if q.canNil {
  1138. x.linef("var %s bool = %s", q.nilVar, q.nilLine.v())
  1139. }
  1140. }
  1141. // var nn int
  1142. // due to omitEmpty, we need to calculate the
  1143. // number of non-empty things we write out first.
  1144. // This is required as we need to pre-determine the size of the container,
  1145. // to support length-prefixing.
  1146. omitEmptySometimes := x.omitEmptyWhen == nil
  1147. omitEmptyAlways := (x.omitEmptyWhen != nil && *(x.omitEmptyWhen))
  1148. // omitEmptyNever := (x.omitEmptyWhen != nil && !*(x.omitEmptyWhen))
  1149. toArraySometimes := x.toArrayWhen == nil
  1150. toArrayAlways := (x.toArrayWhen != nil && *(x.toArrayWhen))
  1151. toArrayNever := (x.toArrayWhen != nil && !(*(x.toArrayWhen)))
  1152. if (omitEmptySometimes && ti.anyOmitEmpty) || omitEmptyAlways {
  1153. x.linef("var %s = [%v]bool{ // should field at this index be written?", numfieldsvar, len(tisfi))
  1154. for _, si := range tisfi {
  1155. if omitEmptySometimes && !si.path.omitEmpty {
  1156. x.linef("true, // %s", si.encName) // si.fieldName)
  1157. continue
  1158. }
  1159. var omitline genBuf
  1160. t2 := genOmitEmptyLinePreChecks(varname, t, si, &omitline, false)
  1161. x.doEncOmitEmptyLine(t2, varname, &omitline)
  1162. x.linef("%s, // %s", omitline.v(), si.encName) // si.fieldName)
  1163. }
  1164. x.line("}")
  1165. x.linef("_ = %s", numfieldsvar)
  1166. }
  1167. if toArraySometimes {
  1168. x.linef("if %s || %s {", ti2arrayvar, struct2arrvar) // if ti.toArray
  1169. }
  1170. if toArraySometimes || toArrayAlways {
  1171. x.linef("z.EncWriteArrayStart(%d)", len(tisfi))
  1172. for j, si := range tisfi {
  1173. doOmitEmptyCheck := (omitEmptySometimes && si.path.omitEmpty) || omitEmptyAlways
  1174. q := &genFQNs[j]
  1175. // if the type of the field is a Selfer, or one of the ones
  1176. if q.canNil {
  1177. x.linef("if %s { z.EncWriteArrayElem(); r.EncodeNil() } else { ", q.nilVar)
  1178. }
  1179. x.linef("z.EncWriteArrayElem()")
  1180. if doOmitEmptyCheck {
  1181. x.linef("if %s[%v] {", numfieldsvar, j)
  1182. }
  1183. x.encVarChkNil(q.fqname, q.sf.Type, false)
  1184. if doOmitEmptyCheck {
  1185. x.linef("} else {")
  1186. x.encZero(q.sf.Type)
  1187. x.linef("}")
  1188. }
  1189. if q.canNil {
  1190. x.line("}")
  1191. }
  1192. }
  1193. x.line("z.EncWriteArrayEnd()")
  1194. }
  1195. if toArraySometimes {
  1196. x.linef("} else {") // if not ti.toArray
  1197. }
  1198. if toArraySometimes || toArrayNever {
  1199. if (omitEmptySometimes && ti.anyOmitEmpty) || omitEmptyAlways {
  1200. x.linef("var %snn%s int", genTempVarPfx, i)
  1201. x.linef("for _, b := range %s { if b { %snn%s++ } }", numfieldsvar, genTempVarPfx, i)
  1202. x.linef("z.EncWriteMapStart(%snn%s)", genTempVarPfx, i)
  1203. x.linef("%snn%s = %v", genTempVarPfx, i, 0)
  1204. } else {
  1205. x.linef("z.EncWriteMapStart(%d)", len(tisfi))
  1206. }
  1207. fn := func(tisfi []*structFieldInfo) {
  1208. for j, si := range tisfi {
  1209. q := &genFQNs[j]
  1210. doOmitEmptyCheck := (omitEmptySometimes && si.path.omitEmpty) || omitEmptyAlways
  1211. if doOmitEmptyCheck {
  1212. x.linef("if %s[%v] {", numfieldsvar, j)
  1213. }
  1214. x.linef("z.EncWriteMapElemKey()")
  1215. // emulate EncStructFieldKey
  1216. switch ti.keyType {
  1217. case valueTypeInt:
  1218. x.linef("r.EncodeInt(z.M.Int(strconv.ParseInt(`%s`, 10, 64)))", si.encName)
  1219. case valueTypeUint:
  1220. x.linef("r.EncodeUint(z.M.Uint(strconv.ParseUint(`%s`, 10, 64)))", si.encName)
  1221. case valueTypeFloat:
  1222. x.linef("r.EncodeFloat64(z.M.Float(strconv.ParseFloat(`%s`, 64)))", si.encName)
  1223. default: // string
  1224. if x.jsonOnlyWhen == nil {
  1225. if si.path.encNameAsciiAlphaNum {
  1226. x.linef(`if z.IsJSONHandle() { z.WriteStr("\"%s\"") } else { `, si.encName)
  1227. }
  1228. x.linef("r.EncodeString(`%s`)", si.encName)
  1229. if si.path.encNameAsciiAlphaNum {
  1230. x.linef("}")
  1231. }
  1232. } else if *(x.jsonOnlyWhen) {
  1233. if si.path.encNameAsciiAlphaNum {
  1234. x.linef(`z.WriteStr("\"%s\"")`, si.encName)
  1235. } else {
  1236. x.linef("r.EncodeString(`%s`)", si.encName)
  1237. }
  1238. } else {
  1239. x.linef("r.EncodeString(`%s`)", si.encName)
  1240. }
  1241. }
  1242. x.line("z.EncWriteMapElemValue()")
  1243. if q.canNil {
  1244. x.line("if " + q.nilVar + " { r.EncodeNil() } else { ")
  1245. x.encVarChkNil(q.fqname, q.sf.Type, false)
  1246. x.line("}")
  1247. } else {
  1248. x.encVarChkNil(q.fqname, q.sf.Type, false)
  1249. }
  1250. if doOmitEmptyCheck {
  1251. x.line("}")
  1252. }
  1253. }
  1254. }
  1255. if genStructCanonical {
  1256. x.linef("if z.EncBasicHandle().Canonical {") // if Canonical block
  1257. fn(ti.sfi.sorted())
  1258. x.linef("} else {") // else !cononical block
  1259. fn(ti.sfi.source())
  1260. x.linef("}") // end if Canonical block
  1261. } else {
  1262. fn(tisfi)
  1263. }
  1264. x.line("z.EncWriteMapEnd()")
  1265. }
  1266. if toArraySometimes {
  1267. x.linef("} ") // end if/else ti.toArray
  1268. }
  1269. }
  1270. func (x *genRunner) encListFallback(varname string, t reflect.Type) {
  1271. x.linef("if %s == nil { r.EncodeNil(); return }", varname)
  1272. elemBytes := t.Elem().Kind() == reflect.Uint8
  1273. if t.AssignableTo(uint8SliceTyp) {
  1274. x.linef("r.EncodeStringBytesRaw([]byte(%s))", varname)
  1275. return
  1276. }
  1277. if t.Kind() == reflect.Array && elemBytes {
  1278. x.linef("r.EncodeStringBytesRaw(((*[%d]byte)(%s))[:])", t.Len(), varname)
  1279. return
  1280. }
  1281. i := x.varsfx()
  1282. if t.Kind() == reflect.Chan {
  1283. type ts struct {
  1284. Label, Chan, Slice, Sfx string
  1285. }
  1286. tm, err := template.New("").Parse(genEncChanTmpl)
  1287. genCheckErr(err)
  1288. x.linef("if %s == nil { r.EncodeNil() } else { ", varname)
  1289. x.linef("var sch%s []%s", i, x.genTypeName(t.Elem()))
  1290. err = tm.Execute(x.w, &ts{"Lsch" + i, varname, "sch" + i, i})
  1291. genCheckErr(err)
  1292. if elemBytes {
  1293. x.linef("r.EncodeStringBytesRaw([]byte(%s))", "sch"+i)
  1294. x.line("}")
  1295. return
  1296. }
  1297. varname = "sch" + i
  1298. }
  1299. x.line("z.EncWriteArrayStart(len(" + varname + "))")
  1300. // x.linef("for _, %sv%s := range %s {", genTempVarPfx, i, varname)
  1301. // x.linef("z.EncWriteArrayElem()")
  1302. // x.encVar(genTempVarPfx+"v"+i, t.Elem())
  1303. // x.line("}")
  1304. x.linef("for %sv%s := range %s {", genTempVarPfx, i, varname)
  1305. x.linef("z.EncWriteArrayElem()")
  1306. x.encVar(fmt.Sprintf("%s[%sv%s]", varname, genTempVarPfx, i), t.Elem())
  1307. x.line("}")
  1308. x.line("z.EncWriteArrayEnd()")
  1309. if t.Kind() == reflect.Chan {
  1310. x.line("}")
  1311. }
  1312. }
  1313. func (x *genRunner) encMapFallback(varname string, t reflect.Type) {
  1314. x.linef("if %s == nil { r.EncodeNil()", varname)
  1315. x.linef("} else if z.EncBasicHandle().Canonical { z.EncEncodeMapNonNil(%s)", varname)
  1316. x.line("} else {")
  1317. i := x.varsfx()
  1318. x.linef("z.EncWriteMapStart(len(%s))", varname)
  1319. x.linef("for %sk%s, %sv%s := range %s {", genTempVarPfx, i, genTempVarPfx, i, varname)
  1320. x.linef("z.EncWriteMapElemKey()")
  1321. x.encVar(genTempVarPfx+"k"+i, t.Key())
  1322. x.line("z.EncWriteMapElemValue()")
  1323. x.encVar(genTempVarPfx+"v"+i, t.Elem())
  1324. x.line("}")
  1325. x.line("z.EncWriteMapEnd()")
  1326. x.line("}")
  1327. }
  1328. func (x *genRunner) decVarInitPtr(varname, nilvar string, t reflect.Type, si *structFieldInfo,
  1329. newbuf, nilbuf *genBuf) (varname3 string, t2 reflect.StructField) {
  1330. //we must accommodate anonymous fields, where the embedded field is a nil pointer in the value.
  1331. // t2 = t.FieldByIndex(si.is)
  1332. varname3 = varname
  1333. t2typ := t
  1334. t2kind := t2typ.Kind()
  1335. var nilbufed bool
  1336. if si != nil {
  1337. fullpath := si.path.fullpath()
  1338. for _, path := range fullpath {
  1339. // only one-level pointers can be seen in a type
  1340. if t2typ.Kind() == reflect.Ptr {
  1341. t2typ = t2typ.Elem()
  1342. }
  1343. t2 = t2typ.Field(int(path.index))
  1344. t2typ = t2.Type
  1345. varname3 = varname3 + "." + t2.Name
  1346. t2kind = t2typ.Kind()
  1347. if t2kind != reflect.Ptr {
  1348. continue
  1349. }
  1350. if newbuf != nil {
  1351. if len(newbuf.buf) > 0 {
  1352. newbuf.s("\n")
  1353. }
  1354. newbuf.f("if %s == nil { %s = new(%s) }", varname3, varname3, x.genTypeName(t2typ.Elem()))
  1355. }
  1356. if nilbuf != nil {
  1357. if !nilbufed {
  1358. nilbuf.s("if ").s(varname3).s(" != nil")
  1359. nilbufed = true
  1360. } else {
  1361. nilbuf.s(" && ").s(varname3).s(" != nil")
  1362. }
  1363. }
  1364. }
  1365. }
  1366. if nilbuf != nil {
  1367. if nilbufed {
  1368. nilbuf.s(" { ").s("// remove the if-true\n")
  1369. }
  1370. if nilvar != "" {
  1371. nilbuf.s(nilvar).s(" = true")
  1372. } else if tk := t2typ.Kind(); tk == reflect.Ptr {
  1373. if strings.IndexByte(varname3, '.') != -1 || strings.IndexByte(varname3, '[') != -1 {
  1374. nilbuf.s(varname3).s(" = nil")
  1375. } else {
  1376. nilbuf.s("*").s(varname3).s(" = ").s(x.genZeroValueR(t2typ.Elem()))
  1377. }
  1378. } else {
  1379. nilbuf.s(varname3).s(" = ").s(x.genZeroValueR(t2typ))
  1380. }
  1381. if nilbufed {
  1382. nilbuf.s("}")
  1383. }
  1384. }
  1385. return
  1386. }
  1387. // decVar takes a variable called varname, of type t
  1388. func (x *genRunner) decVarMain(varname, rand string, t reflect.Type, checkNotNil bool) {
  1389. // We only encode as nil if a nillable value.
  1390. // This removes some of the wasted checks for TryDecodeAsNil.
  1391. // We need to think about this more, to see what happens if omitempty, etc
  1392. // cause a nil value to be stored when something is expected.
  1393. // This could happen when decoding from a struct encoded as an array.
  1394. // For that, decVar should be called with canNil=true, to force true as its value.
  1395. var varname2 string
  1396. if t.Kind() != reflect.Ptr {
  1397. if t.PkgPath() != "" || !x.decTryAssignPrimitive(varname, t, false) {
  1398. x.dec(varname, t, false)
  1399. }
  1400. } else {
  1401. if checkNotNil {
  1402. x.linef("if %s == nil { %s = new(%s) }", varname, varname, x.genTypeName(t.Elem()))
  1403. }
  1404. // Ensure we set underlying ptr to a non-nil value (so we can deref to it later).
  1405. // There's a chance of a **T in here which is nil.
  1406. var ptrPfx string
  1407. for t = t.Elem(); t.Kind() == reflect.Ptr; t = t.Elem() {
  1408. ptrPfx += "*"
  1409. if checkNotNil {
  1410. x.linef("if %s%s == nil { %s%s = new(%s)}", ptrPfx, varname, ptrPfx, varname, x.genTypeName(t))
  1411. }
  1412. }
  1413. // Should we create temp var if a slice/map indexing? No. dec(...) can now handle it.
  1414. if ptrPfx == "" {
  1415. x.dec(varname, t, true)
  1416. } else {
  1417. varname2 = genTempVarPfx + "z" + rand
  1418. x.line(varname2 + " := " + ptrPfx + varname)
  1419. x.dec(varname2, t, true)
  1420. }
  1421. }
  1422. }
  1423. // decVar takes a variable called varname, of type t
  1424. func (x *genRunner) decVar(varname, nilvar string, t reflect.Type, canBeNil, checkNotNil bool) {
  1425. // We only encode as nil if a nillable value.
  1426. // This removes some of the wasted checks for TryDecodeAsNil.
  1427. // We need to think about this more, to see what happens if omitempty, etc
  1428. // cause a nil value to be stored when something is expected.
  1429. // This could happen when decoding from a struct encoded as an array.
  1430. // For that, decVar should be called with canNil=true, to force true as its value.
  1431. i := x.varsfx()
  1432. if t.Kind() == reflect.Ptr {
  1433. var buf genBuf
  1434. x.decVarInitPtr(varname, nilvar, t, nil, nil, &buf)
  1435. x.linef("if r.TryNil() { %s } else {", buf.buf)
  1436. x.decVarMain(varname, i, t, checkNotNil)
  1437. x.line("} ")
  1438. } else {
  1439. x.decVarMain(varname, i, t, checkNotNil)
  1440. }
  1441. }
  1442. // dec will decode a variable (varname) of type t or ptrTo(t) if isptr==true.
  1443. func (x *genRunner) dec(varname string, t reflect.Type, isptr bool) {
  1444. // assumptions:
  1445. // - the varname is to a pointer already. No need to take address of it
  1446. // - t is always a baseType T (not a *T, etc).
  1447. rtid := rt2id(t)
  1448. ti2 := x.ti.get(rtid, t)
  1449. // check if
  1450. // - type is time.Time, Raw, RawExt
  1451. // - the type implements (Text|JSON|Binary)(Unm|M)arshal
  1452. mi := x.varsfx()
  1453. var hasIf genIfClause
  1454. defer hasIf.end(x)
  1455. var ptrPfx, addrPfx string
  1456. if isptr {
  1457. ptrPfx = "*"
  1458. } else {
  1459. addrPfx = "&"
  1460. }
  1461. if t == timeTyp {
  1462. x.linef("%s z.DecBasicHandle().TimeBuiltin() { %s%v = r.DecodeTime()", hasIf.c(false), ptrPfx, varname)
  1463. // return
  1464. }
  1465. if t == rawTyp {
  1466. x.linef("%s %s%v = z.DecRaw()", hasIf.c(true), ptrPfx, varname)
  1467. return
  1468. }
  1469. if t == rawExtTyp {
  1470. x.linef("%s r.DecodeExt(%s%v, 0, nil)", hasIf.c(true), addrPfx, varname)
  1471. return
  1472. }
  1473. // only check for extensions if extensions are configured,
  1474. // and the type is named, and has a packagePath,
  1475. // and this is not the CodecEncodeSelf or CodecDecodeSelf method (i.e. it is not a Selfer)
  1476. // xdebugf("genRunner.dec: varname: %v, t: %v, genImportPath: %v, t.Name: %v", varname, t, genImportPath(t), t.Name())
  1477. if !x.nx && varname != genTopLevelVarName && t != genStringDecAsBytesTyp &&
  1478. t != genStringDecZCTyp && genImportPath(t) != "" && t.Name() != "" {
  1479. // first check if extensions are configued, before doing the interface conversion
  1480. yy := fmt.Sprintf("%sxt%s", genTempVarPfx, mi)
  1481. x.linef("%s %s := z.Extension(%s); %s != nil { z.DecExtension(%s%s, %s) ", hasIf.c(false), yy, varname, yy, addrPfx, varname, yy)
  1482. }
  1483. if x.checkForSelfer(t, varname) {
  1484. if ti2.flagSelfer {
  1485. x.linef("%s %s.CodecDecodeSelf(d)", hasIf.c(true), varname)
  1486. return
  1487. }
  1488. if ti2.flagSelferPtr {
  1489. x.linef("%s %s.CodecDecodeSelf(d)", hasIf.c(true), varname)
  1490. return
  1491. }
  1492. if _, ok := x.td[rtid]; ok {
  1493. x.linef("%s %s.CodecDecodeSelf(d)", hasIf.c(true), varname)
  1494. return
  1495. }
  1496. }
  1497. inlist := false
  1498. for _, t0 := range x.t {
  1499. if t == t0 {
  1500. inlist = true
  1501. if x.checkForSelfer(t, varname) {
  1502. x.linef("%s %s.CodecDecodeSelf(d)", hasIf.c(true), varname)
  1503. return
  1504. }
  1505. break
  1506. }
  1507. }
  1508. var rtidAdded bool
  1509. if t == x.tc {
  1510. x.td[rtid] = true
  1511. rtidAdded = true
  1512. }
  1513. if ti2.flagBinaryUnmarshaler {
  1514. x.linef("%s z.DecBinary() { z.DecBinaryUnmarshal(%s%v) ", hasIf.c(false), ptrPfx, varname)
  1515. } else if ti2.flagBinaryUnmarshalerPtr {
  1516. x.linef("%s z.DecBinary() { z.DecBinaryUnmarshal(%s%v) ", hasIf.c(false), addrPfx, varname)
  1517. }
  1518. if ti2.flagJsonUnmarshaler {
  1519. x.linef("%s !z.DecBinary() && z.IsJSONHandle() { z.DecJSONUnmarshal(%s%v)", hasIf.c(false), ptrPfx, varname)
  1520. } else if ti2.flagJsonUnmarshalerPtr {
  1521. x.linef("%s !z.DecBinary() && z.IsJSONHandle() { z.DecJSONUnmarshal(%s%v)", hasIf.c(false), addrPfx, varname)
  1522. } else if ti2.flagTextUnmarshaler {
  1523. x.linef("%s !z.DecBinary() { z.DecTextUnmarshal(%s%v)", hasIf.c(false), ptrPfx, varname)
  1524. } else if ti2.flagTextUnmarshalerPtr {
  1525. x.linef("%s !z.DecBinary() { z.DecTextUnmarshal(%s%v)", hasIf.c(false), addrPfx, varname)
  1526. }
  1527. x.lineIf(hasIf.c(true))
  1528. if x.decTryAssignPrimitive(varname, t, isptr) {
  1529. return
  1530. }
  1531. switch t.Kind() {
  1532. case reflect.Chan:
  1533. x.xtraSM(varname, t, ti2, false, isptr)
  1534. case reflect.Array:
  1535. _, rtidu := genFastpathUnderlying(t, rtid, ti2)
  1536. if fastpathAvIndex(rtidu) != -1 {
  1537. g := x.newFastpathGenV(ti2.key)
  1538. x.linef("z.F.%sN((%s)(%s[:]), d)", g.MethodNamePfx("Dec", false), x.genTypeName(ti2.key), varname)
  1539. } else {
  1540. x.xtraSM(varname, t, ti2, false, isptr)
  1541. }
  1542. case reflect.Slice:
  1543. // if a []byte, call dedicated function
  1544. // if a known fastpath slice, call dedicated function
  1545. // else write encode function in-line.
  1546. // - if elements are primitives or Selfers, call dedicated function on each member.
  1547. // - else call Encoder.encode(XXX) on it.
  1548. if rtid == uint8SliceTypId {
  1549. x.linef("%s%s = z.DecodeBytesInto(%s(%s[]byte)(%s))", ptrPfx, varname, ptrPfx, ptrPfx, varname)
  1550. } else {
  1551. tu, rtidu := genFastpathUnderlying(t, rtid, ti2)
  1552. if fastpathAvIndex(rtidu) != -1 {
  1553. g := x.newFastpathGenV(tu)
  1554. if rtid == rtidu {
  1555. x.linef("z.F.%sX(%s%s, d)", g.MethodNamePfx("Dec", false), addrPfx, varname)
  1556. } else {
  1557. x.linef("z.F.%sX((*%s)(%s%s), d)", g.MethodNamePfx("Dec", false), x.genTypeName(tu), addrPfx, varname)
  1558. }
  1559. } else {
  1560. x.xtraSM(varname, t, ti2, false, isptr)
  1561. // x.decListFallback(varname, rtid, false, t)
  1562. }
  1563. }
  1564. case reflect.Map:
  1565. // if a known fastpath map, call dedicated function
  1566. // else write encode function in-line.
  1567. // - if elements are primitives or Selfers, call dedicated function on each member.
  1568. // - else call Encoder.encode(XXX) on it.
  1569. tu, rtidu := genFastpathUnderlying(t, rtid, ti2)
  1570. if fastpathAvIndex(rtidu) != -1 {
  1571. g := x.newFastpathGenV(tu)
  1572. if rtid == rtidu {
  1573. x.linef("z.F.%sX(%s%s, d)", g.MethodNamePfx("Dec", false), addrPfx, varname)
  1574. } else {
  1575. x.linef("z.F.%sX((*%s)(%s%s), d)", g.MethodNamePfx("Dec", false), x.genTypeName(tu), addrPfx, varname)
  1576. }
  1577. } else {
  1578. x.xtraSM(varname, t, ti2, false, isptr)
  1579. }
  1580. case reflect.Struct:
  1581. if inlist {
  1582. // no need to create temp variable if isptr, or x.F or x[F]
  1583. if isptr || strings.IndexByte(varname, '.') != -1 || strings.IndexByte(varname, '[') != -1 {
  1584. x.decStruct(varname, rtid, t)
  1585. } else {
  1586. varname2 := genTempVarPfx + "j" + mi
  1587. x.line(varname2 + " := &" + varname)
  1588. x.decStruct(varname2, rtid, t)
  1589. }
  1590. } else {
  1591. // delete(x.td, rtid)
  1592. x.line("z.DecFallback(" + addrPfx + varname + ", false)")
  1593. }
  1594. default:
  1595. if rtidAdded {
  1596. delete(x.te, rtid)
  1597. }
  1598. x.line("z.DecFallback(" + addrPfx + varname + ", true)")
  1599. }
  1600. }
  1601. func (x *genRunner) decTryAssignPrimitive(varname string, t reflect.Type, isptr bool) (done bool) {
  1602. // This should only be used for exact primitives (ie un-named types).
  1603. // Named types may be implementations of Selfer, Unmarshaler, etc.
  1604. // They should be handled by dec(...)
  1605. var ptr string
  1606. if isptr {
  1607. ptr = "*"
  1608. }
  1609. switch t.Kind() {
  1610. case reflect.Int:
  1611. x.linef("%s%s = (%s)(z.C.IntV(r.DecodeInt64(), codecSelferBitsize%s))", ptr, varname, x.genTypeName(t), x.xs)
  1612. case reflect.Int8:
  1613. x.linef("%s%s = (%s)(z.C.IntV(r.DecodeInt64(), 8))", ptr, varname, x.genTypeName(t))
  1614. case reflect.Int16:
  1615. x.linef("%s%s = (%s)(z.C.IntV(r.DecodeInt64(), 16))", ptr, varname, x.genTypeName(t))
  1616. case reflect.Int32:
  1617. x.linef("%s%s = (%s)(z.C.IntV(r.DecodeInt64(), 32))", ptr, varname, x.genTypeName(t))
  1618. case reflect.Int64:
  1619. x.linef("%s%s = (%s)(r.DecodeInt64())", ptr, varname, x.genTypeName(t))
  1620. case reflect.Uint:
  1621. x.linef("%s%s = (%s)(z.C.UintV(r.DecodeUint64(), codecSelferBitsize%s))", ptr, varname, x.genTypeName(t), x.xs)
  1622. case reflect.Uint8:
  1623. x.linef("%s%s = (%s)(z.C.UintV(r.DecodeUint64(), 8))", ptr, varname, x.genTypeName(t))
  1624. case reflect.Uint16:
  1625. x.linef("%s%s = (%s)(z.C.UintV(r.DecodeUint64(), 16))", ptr, varname, x.genTypeName(t))
  1626. case reflect.Uint32:
  1627. x.linef("%s%s = (%s)(z.C.UintV(r.DecodeUint64(), 32))", ptr, varname, x.genTypeName(t))
  1628. case reflect.Uint64:
  1629. x.linef("%s%s = (%s)(r.DecodeUint64())", ptr, varname, x.genTypeName(t))
  1630. case reflect.Uintptr:
  1631. x.linef("%s%s = (%s)(z.C.UintV(r.DecodeUint64(), codecSelferBitsize%s))", ptr, varname, x.genTypeName(t), x.xs)
  1632. case reflect.Float32:
  1633. x.linef("%s%s = (%s)(z.DecDecodeFloat32())", ptr, varname, x.genTypeName(t))
  1634. case reflect.Float64:
  1635. x.linef("%s%s = (%s)(r.DecodeFloat64())", ptr, varname, x.genTypeName(t))
  1636. case reflect.Complex64:
  1637. x.linef("%s%s = (%s)(complex(z.DecDecodeFloat32(), 0))", ptr, varname, x.genTypeName(t))
  1638. case reflect.Complex128:
  1639. x.linef("%s%s = (%s)(complex(r.DecodeFloat64(), 0))", ptr, varname, x.genTypeName(t))
  1640. case reflect.Bool:
  1641. x.linef("%s%s = (%s)(r.DecodeBool())", ptr, varname, x.genTypeName(t))
  1642. case reflect.String:
  1643. if t == genStringDecAsBytesTyp {
  1644. x.linef("%s%s = r.DecodeStringAsBytes()", ptr, varname)
  1645. } else if t == genStringDecZCTyp {
  1646. x.linef("%s%s = (string)(z.DecStringZC(r.DecodeStringAsBytes()))", ptr, varname)
  1647. } else {
  1648. x.linef("%s%s = (%s)(z.DecStringZC(r.DecodeStringAsBytes()))", ptr, varname, x.genTypeName(t))
  1649. }
  1650. default:
  1651. return false
  1652. }
  1653. return true
  1654. }
  1655. func (x *genRunner) decListFallback(varname string, rtid uintptr, t reflect.Type) {
  1656. if t.AssignableTo(uint8SliceTyp) {
  1657. x.line("*" + varname + " = z.DecodeBytesInto(*((*[]byte)(" + varname + ")))")
  1658. return
  1659. }
  1660. if t.Kind() == reflect.Array && t.Elem().Kind() == reflect.Uint8 {
  1661. x.linef("r.DecodeBytes( ((*[%d]byte)(%s))[:])", t.Len(), varname)
  1662. return
  1663. }
  1664. type tstruc struct {
  1665. TempVar string
  1666. Sfx string
  1667. Rand string
  1668. Varname string
  1669. CTyp string
  1670. Typ string
  1671. Immutable bool
  1672. Size int
  1673. }
  1674. telem := t.Elem()
  1675. ts := tstruc{genTempVarPfx, x.xs, x.varsfx(), varname, x.genTypeName(t), x.genTypeName(telem), genIsImmutable(telem), int(telem.Size())}
  1676. funcs := make(template.FuncMap)
  1677. funcs["decLineVar"] = func(varname string) string {
  1678. x.decVar(varname, "", telem, false, true)
  1679. return ""
  1680. }
  1681. funcs["var"] = func(s string) string {
  1682. return ts.TempVar + s + ts.Rand
  1683. }
  1684. funcs["xs"] = func() string {
  1685. return ts.Sfx
  1686. }
  1687. funcs["zero"] = func() string {
  1688. return x.genZeroValueR(telem)
  1689. }
  1690. funcs["isArray"] = func() bool {
  1691. return t.Kind() == reflect.Array
  1692. }
  1693. funcs["isSlice"] = func() bool {
  1694. return t.Kind() == reflect.Slice
  1695. }
  1696. funcs["isChan"] = func() bool {
  1697. return t.Kind() == reflect.Chan
  1698. }
  1699. tm, err := template.New("").Funcs(funcs).Parse(genDecListTmpl)
  1700. genCheckErr(err)
  1701. genCheckErr(tm.Execute(x.w, &ts))
  1702. }
  1703. func (x *genRunner) decMapFallback(varname string, rtid uintptr, t reflect.Type) {
  1704. type tstruc struct {
  1705. TempVar string
  1706. Sfx string
  1707. Rand string
  1708. Varname string
  1709. KTyp string
  1710. Typ string
  1711. Size int
  1712. }
  1713. telem := t.Elem()
  1714. tkey := t.Key()
  1715. ts := tstruc{
  1716. genTempVarPfx, x.xs, x.varsfx(), varname, x.genTypeName(tkey),
  1717. x.genTypeName(telem), int(telem.Size() + tkey.Size()),
  1718. }
  1719. funcs := make(template.FuncMap)
  1720. funcs["decElemZero"] = func() string {
  1721. return x.genZeroValueR(telem)
  1722. }
  1723. funcs["decElemKindImmutable"] = func() bool {
  1724. return genIsImmutable(telem)
  1725. }
  1726. funcs["decElemKindPtr"] = func() bool {
  1727. return telem.Kind() == reflect.Ptr
  1728. }
  1729. funcs["decElemKindIntf"] = func() bool {
  1730. return telem.Kind() == reflect.Interface
  1731. }
  1732. funcs["decLineVarKStrBytes"] = func(varname string) string {
  1733. x.decVar(varname, "", genStringDecAsBytesTyp, false, true)
  1734. return ""
  1735. }
  1736. funcs["decLineVarKStrZC"] = func(varname string) string {
  1737. x.decVar(varname, "", genStringDecZCTyp, false, true)
  1738. return ""
  1739. }
  1740. funcs["decLineVarK"] = func(varname string) string {
  1741. x.decVar(varname, "", tkey, false, true)
  1742. return ""
  1743. }
  1744. funcs["decLineVar"] = func(varname, decodedNilVarname string) string {
  1745. x.decVar(varname, decodedNilVarname, telem, false, true)
  1746. return ""
  1747. }
  1748. funcs["var"] = func(s string) string {
  1749. return ts.TempVar + s + ts.Rand
  1750. }
  1751. funcs["xs"] = func() string {
  1752. return ts.Sfx
  1753. }
  1754. tm, err := template.New("").Funcs(funcs).Parse(genDecMapTmpl)
  1755. genCheckErr(err)
  1756. genCheckErr(tm.Execute(x.w, &ts))
  1757. }
  1758. func (x *genRunner) decStructMapSwitch(kName string, varname string, rtid uintptr, t reflect.Type) {
  1759. ti := x.ti.get(rtid, t)
  1760. tisfi := ti.sfi.source() // always use sequence from file. decStruct expects same thing.
  1761. x.line("switch string(" + kName + ") {")
  1762. var newbuf, nilbuf genBuf
  1763. for _, si := range tisfi {
  1764. x.line("case \"" + si.encName + "\":")
  1765. newbuf.reset()
  1766. nilbuf.reset()
  1767. varname3, t2 := x.decVarInitPtr(varname, "", t, si, &newbuf, &nilbuf)
  1768. if len(newbuf.buf) > 0 {
  1769. x.linef("if r.TryNil() { %s } else { %s", nilbuf.buf, newbuf.buf)
  1770. }
  1771. x.decVarMain(varname3, x.varsfx(), t2.Type, false)
  1772. if len(newbuf.buf) > 0 {
  1773. x.line("}")
  1774. }
  1775. }
  1776. x.line("default:")
  1777. // pass the slice here, so that the string will not escape, and maybe save allocation
  1778. x.linef("z.DecStructFieldNotFound(-1, string(%s))", kName)
  1779. x.linef("} // end switch %s", kName)
  1780. }
  1781. func (x *genRunner) decStructMap(varname, lenvarname string, rtid uintptr, t reflect.Type, style genStructMapStyle) {
  1782. tpfx := genTempVarPfx
  1783. ti := x.ti.get(rtid, t)
  1784. i := x.varsfx()
  1785. kName := tpfx + "s" + i
  1786. switch style {
  1787. case genStructMapStyleLenPrefix:
  1788. x.linef("for %sj%s := 0; %sj%s < %s; %sj%s++ {", tpfx, i, tpfx, i, lenvarname, tpfx, i)
  1789. case genStructMapStyleCheckBreak:
  1790. x.linef("for %sj%s := 0; !z.DecCheckBreak(); %sj%s++ {", tpfx, i, tpfx, i)
  1791. default: // 0, otherwise.
  1792. x.linef("var %shl%s bool = %s >= 0", tpfx, i, lenvarname) // has length
  1793. x.linef("for %sj%s := 0; ; %sj%s++ {", tpfx, i, tpfx, i)
  1794. x.linef("if %shl%s { if %sj%s >= %s { break }", tpfx, i, tpfx, i, lenvarname)
  1795. x.line("} else { if z.DecCheckBreak() { break }; }")
  1796. }
  1797. x.line("z.DecReadMapElemKey()")
  1798. // emulate decstructfieldkey
  1799. switch ti.keyType {
  1800. case valueTypeInt:
  1801. x.linef("%s := strconv.AppendInt(z.DecScratchArrayBuffer()[:0], r.DecodeInt64(), 10)", kName)
  1802. case valueTypeUint:
  1803. x.linef("%s := strconv.AppendUint(z.DecScratchArrayBuffer()[:0], r.DecodeUint64(), 10)", kName)
  1804. case valueTypeFloat:
  1805. x.linef("%s := strconv.AppendFloat(z.DecScratchArrayBuffer()[:0], r.DecodeFloat64(), 'f', -1, 64)", kName)
  1806. default: // string
  1807. x.linef("%s := r.DecodeStringAsBytes()", kName)
  1808. }
  1809. x.line("z.DecReadMapElemValue()")
  1810. x.decStructMapSwitch(kName, varname, rtid, t)
  1811. x.line("} // end for " + tpfx + "j" + i)
  1812. }
  1813. func (x *genRunner) decStructArray(varname, lenvarname, breakString string, rtid uintptr, t reflect.Type) {
  1814. tpfx := genTempVarPfx
  1815. i := x.varsfx()
  1816. ti := x.ti.get(rtid, t)
  1817. tisfi := ti.sfi.source() // always use sequence from file. decStruct expects same thing.
  1818. x.linef("var %sj%s int", tpfx, i)
  1819. x.linef("var %sb%s bool", tpfx, i) // break
  1820. x.linef("var %shl%s bool = %s >= 0", tpfx, i, lenvarname) // has length
  1821. if !genDecStructArrayInlineLoopCheck {
  1822. x.linef("var %sfn%s = func() bool { ", tpfx, i)
  1823. x.linef("%sj%s++; if %shl%s { %sb%s = %sj%s > %s } else { %sb%s = z.DecCheckBreak() };",
  1824. tpfx, i, tpfx, i, tpfx, i,
  1825. tpfx, i, lenvarname, tpfx, i)
  1826. x.linef("if %sb%s { z.DecReadArrayEnd(); return true }; return false", tpfx, i)
  1827. x.linef("} // end func %sfn%s", tpfx, i)
  1828. }
  1829. var newbuf, nilbuf genBuf
  1830. for _, si := range tisfi {
  1831. if genDecStructArrayInlineLoopCheck {
  1832. x.linef("%sj%s++; if %shl%s { %sb%s = %sj%s > %s } else { %sb%s = z.DecCheckBreak() }",
  1833. tpfx, i, tpfx, i, tpfx, i,
  1834. tpfx, i, lenvarname, tpfx, i)
  1835. x.linef("if %sb%s { z.DecReadArrayEnd(); %s }", tpfx, i, breakString)
  1836. } else {
  1837. x.linef("if %sfn%s() { %s }", tpfx, i, breakString)
  1838. }
  1839. x.line("z.DecReadArrayElem()")
  1840. newbuf.reset()
  1841. nilbuf.reset()
  1842. varname3, t2 := x.decVarInitPtr(varname, "", t, si, &newbuf, &nilbuf)
  1843. if len(newbuf.buf) > 0 {
  1844. x.linef("if r.TryNil() { %s } else { %s", nilbuf.buf, newbuf.buf)
  1845. }
  1846. x.decVarMain(varname3, x.varsfx(), t2.Type, false)
  1847. if len(newbuf.buf) > 0 {
  1848. x.line("}")
  1849. }
  1850. }
  1851. // read remaining values and throw away.
  1852. x.line("for {")
  1853. x.linef("%sj%s++; if %shl%s { %sb%s = %sj%s > %s } else { %sb%s = z.DecCheckBreak() }",
  1854. tpfx, i, tpfx, i, tpfx, i,
  1855. tpfx, i, lenvarname, tpfx, i)
  1856. x.linef("if %sb%s { break }", tpfx, i)
  1857. x.line("z.DecReadArrayElem()")
  1858. x.linef(`z.DecStructFieldNotFound(%sj%s - 1, "")`, tpfx, i)
  1859. x.line("}")
  1860. }
  1861. func (x *genRunner) decStruct(varname string, rtid uintptr, t reflect.Type) {
  1862. // varname MUST be a ptr, or a struct field or a slice element.
  1863. i := x.varsfx()
  1864. x.linef("%sct%s := r.ContainerType()", genTempVarPfx, i)
  1865. x.linef("if %sct%s == codecSelferValueTypeNil%s {", genTempVarPfx, i, x.xs)
  1866. x.linef("*(%s) = %s{}", varname, x.genTypeName(t))
  1867. x.linef("} else if %sct%s == codecSelferValueTypeMap%s {", genTempVarPfx, i, x.xs)
  1868. x.line(genTempVarPfx + "l" + i + " := z.DecReadMapStart()")
  1869. x.linef("if %sl%s == 0 {", genTempVarPfx, i)
  1870. if genUseOneFunctionForDecStructMap {
  1871. x.line("} else { ")
  1872. x.linef("%s.codecDecodeSelfFromMap(%sl%s, d)", varname, genTempVarPfx, i)
  1873. } else {
  1874. x.line("} else if " + genTempVarPfx + "l" + i + " > 0 { ")
  1875. x.line(varname + ".codecDecodeSelfFromMapLenPrefix(" + genTempVarPfx + "l" + i + ", d)")
  1876. x.line("} else {")
  1877. x.line(varname + ".codecDecodeSelfFromMapCheckBreak(" + genTempVarPfx + "l" + i + ", d)")
  1878. }
  1879. x.line("}")
  1880. x.line("z.DecReadMapEnd()")
  1881. // else if container is array
  1882. x.linef("} else if %sct%s == codecSelferValueTypeArray%s {", genTempVarPfx, i, x.xs)
  1883. x.line(genTempVarPfx + "l" + i + " := z.DecReadArrayStart()")
  1884. x.linef("if %sl%s != 0 {", genTempVarPfx, i)
  1885. x.linef("%s.codecDecodeSelfFromArray(%sl%s, d)", varname, genTempVarPfx, i)
  1886. x.line("}")
  1887. x.line("z.DecReadArrayEnd()")
  1888. // else panic
  1889. x.line("} else { ")
  1890. x.line("panic(errCodecSelferOnlyMapOrArrayEncodeToStruct" + x.xs + ")")
  1891. x.line("} ")
  1892. }
  1893. // --------
  1894. type fastpathGenV struct {
  1895. // fastpathGenV is either a primitive (Primitive != "") or a map (MapKey != "") or a slice
  1896. MapKey string
  1897. Elem string
  1898. Primitive string
  1899. Size int
  1900. NoCanonical bool
  1901. }
  1902. func (x *genRunner) newFastpathGenV(t reflect.Type) (v fastpathGenV) {
  1903. v.NoCanonical = !genFastpathCanonical
  1904. switch t.Kind() {
  1905. case reflect.Slice, reflect.Array:
  1906. te := t.Elem()
  1907. v.Elem = x.genTypeName(te)
  1908. v.Size = int(te.Size())
  1909. case reflect.Map:
  1910. te := t.Elem()
  1911. tk := t.Key()
  1912. v.Elem = x.genTypeName(te)
  1913. v.MapKey = x.genTypeName(tk)
  1914. v.Size = int(te.Size() + tk.Size())
  1915. default:
  1916. halt.onerror(errGenUnexpectedTypeFastpath)
  1917. }
  1918. return
  1919. }
  1920. func (x *fastpathGenV) MethodNamePfx(prefix string, prim bool) string {
  1921. var name []byte
  1922. if prefix != "" {
  1923. name = append(name, prefix...)
  1924. }
  1925. if prim {
  1926. name = append(name, genTitleCaseName(x.Primitive)...)
  1927. } else {
  1928. if x.MapKey == "" {
  1929. name = append(name, "Slice"...)
  1930. } else {
  1931. name = append(name, "Map"...)
  1932. name = append(name, genTitleCaseName(x.MapKey)...)
  1933. }
  1934. name = append(name, genTitleCaseName(x.Elem)...)
  1935. }
  1936. return string(name)
  1937. }
  1938. // genImportPath returns import path of a non-predeclared named typed, or an empty string otherwise.
  1939. //
  1940. // This handles the misbehaviour that occurs when 1.5-style vendoring is enabled,
  1941. // where PkgPath returns the full path, including the vendoring pre-fix that should have been stripped.
  1942. // We strip it here.
  1943. func genImportPath(t reflect.Type) (s string) {
  1944. s = t.PkgPath()
  1945. if genCheckVendor {
  1946. // HACK: always handle vendoring. It should be typically on in go 1.6, 1.7
  1947. s = genStripVendor(s)
  1948. }
  1949. return
  1950. }
  1951. // A go identifier is (letter|_)[letter|number|_]*
  1952. func genGoIdentifier(s string, checkFirstChar bool) string {
  1953. b := make([]byte, 0, len(s))
  1954. t := make([]byte, 4)
  1955. var n int
  1956. for i, r := range s {
  1957. if checkFirstChar && i == 0 && !unicode.IsLetter(r) {
  1958. b = append(b, '_')
  1959. }
  1960. // r must be unicode_letter, unicode_digit or _
  1961. if unicode.IsLetter(r) || unicode.IsDigit(r) {
  1962. n = utf8.EncodeRune(t, r)
  1963. b = append(b, t[:n]...)
  1964. } else {
  1965. b = append(b, '_')
  1966. }
  1967. }
  1968. return string(b)
  1969. }
  1970. func genNonPtr(t reflect.Type) reflect.Type {
  1971. for t.Kind() == reflect.Ptr {
  1972. t = t.Elem()
  1973. }
  1974. return t
  1975. }
  1976. func genFastpathUnderlying(t reflect.Type, rtid uintptr, ti *typeInfo) (tu reflect.Type, rtidu uintptr) {
  1977. tu = t
  1978. rtidu = rtid
  1979. if ti.flagHasPkgPath {
  1980. tu = ti.fastpathUnderlying
  1981. rtidu = rt2id(tu)
  1982. }
  1983. return
  1984. }
  1985. func genTitleCaseName(s string) string {
  1986. switch s {
  1987. case "interface{}", "interface {}":
  1988. return "Intf"
  1989. case "[]byte", "[]uint8", "bytes":
  1990. return "Bytes"
  1991. default:
  1992. return strings.ToUpper(s[0:1]) + s[1:]
  1993. }
  1994. }
  1995. func genMethodNameT(t reflect.Type, tRef reflect.Type) (n string) {
  1996. var ptrPfx string
  1997. for t.Kind() == reflect.Ptr {
  1998. ptrPfx += "Ptrto"
  1999. t = t.Elem()
  2000. }
  2001. tstr := t.String()
  2002. if tn := t.Name(); tn != "" {
  2003. if tRef != nil && genImportPath(t) == genImportPath(tRef) {
  2004. return ptrPfx + tn
  2005. } else {
  2006. if genQNameRegex.MatchString(tstr) {
  2007. return ptrPfx + strings.Replace(tstr, ".", "_", 1000)
  2008. } else {
  2009. return ptrPfx + genCustomTypeName(tstr)
  2010. }
  2011. }
  2012. }
  2013. switch t.Kind() {
  2014. case reflect.Map:
  2015. return ptrPfx + "Map" + genMethodNameT(t.Key(), tRef) + genMethodNameT(t.Elem(), tRef)
  2016. case reflect.Slice:
  2017. return ptrPfx + "Slice" + genMethodNameT(t.Elem(), tRef)
  2018. case reflect.Array:
  2019. return ptrPfx + "Array" + strconv.FormatInt(int64(t.Len()), 10) + genMethodNameT(t.Elem(), tRef)
  2020. case reflect.Chan:
  2021. var cx string
  2022. switch t.ChanDir() {
  2023. case reflect.SendDir:
  2024. cx = "ChanSend"
  2025. case reflect.RecvDir:
  2026. cx = "ChanRecv"
  2027. default:
  2028. cx = "Chan"
  2029. }
  2030. return ptrPfx + cx + genMethodNameT(t.Elem(), tRef)
  2031. default:
  2032. if t == intfTyp {
  2033. return ptrPfx + "Interface"
  2034. } else {
  2035. if tRef != nil && genImportPath(t) == genImportPath(tRef) {
  2036. if t.Name() != "" {
  2037. return ptrPfx + t.Name()
  2038. } else {
  2039. return ptrPfx + genCustomTypeName(tstr)
  2040. }
  2041. } else {
  2042. // best way to get the package name inclusive
  2043. // return ptrPfx + strings.Replace(tstr, ".", "_", 1000)
  2044. // return ptrPfx + genBase64enc.EncodeToString([]byte(tstr))
  2045. if t.Name() != "" && genQNameRegex.MatchString(tstr) {
  2046. return ptrPfx + strings.Replace(tstr, ".", "_", 1000)
  2047. } else {
  2048. return ptrPfx + genCustomTypeName(tstr)
  2049. }
  2050. }
  2051. }
  2052. }
  2053. }
  2054. // genCustomNameForType base64encodes the t.String() value in such a way
  2055. // that it can be used within a function name.
  2056. func genCustomTypeName(tstr string) string {
  2057. len2 := genBase64enc.EncodedLen(len(tstr))
  2058. bufx := make([]byte, len2)
  2059. genBase64enc.Encode(bufx, []byte(tstr))
  2060. for i := len2 - 1; i >= 0; i-- {
  2061. if bufx[i] == '=' {
  2062. len2--
  2063. } else {
  2064. break
  2065. }
  2066. }
  2067. return string(bufx[:len2])
  2068. }
  2069. func genIsImmutable(t reflect.Type) (v bool) {
  2070. return scalarBitset.isset(byte(t.Kind()))
  2071. }
  2072. type genInternal struct {
  2073. Version int
  2074. Values []fastpathGenV
  2075. Formats []string
  2076. }
  2077. func (x genInternal) FastpathLen() (l int) {
  2078. for _, v := range x.Values {
  2079. // if v.Primitive == "" && !(v.MapKey == "" && v.Elem == "uint8") {
  2080. if v.Primitive == "" {
  2081. l++
  2082. }
  2083. }
  2084. return
  2085. }
  2086. func genInternalZeroValue(s string) string {
  2087. switch s {
  2088. case "interface{}", "interface {}":
  2089. return "nil"
  2090. case "[]byte", "[]uint8", "bytes":
  2091. return "nil"
  2092. case "bool":
  2093. return "false"
  2094. case "string":
  2095. return `""`
  2096. default:
  2097. return "0"
  2098. }
  2099. }
  2100. var genInternalNonZeroValueIdx [6]uint64
  2101. var genInternalNonZeroValueStrs = [...][6]string{
  2102. {`"string-is-an-interface-1"`, "true", `"some-string-1"`, `[]byte("some-string-1")`, "11.1", "111"},
  2103. {`"string-is-an-interface-2"`, "false", `"some-string-2"`, `[]byte("some-string-2")`, "22.2", "77"},
  2104. {`"string-is-an-interface-3"`, "true", `"some-string-3"`, `[]byte("some-string-3")`, "33.3e3", "127"},
  2105. }
  2106. // Note: last numbers must be in range: 0-127 (as they may be put into a int8, uint8, etc)
  2107. func genInternalNonZeroValue(s string) string {
  2108. var i int
  2109. switch s {
  2110. case "interface{}", "interface {}":
  2111. i = 0
  2112. case "bool":
  2113. i = 1
  2114. case "string":
  2115. i = 2
  2116. case "bytes", "[]byte", "[]uint8":
  2117. i = 3
  2118. case "float32", "float64", "float", "double", "complex", "complex64", "complex128":
  2119. i = 4
  2120. default:
  2121. i = 5
  2122. }
  2123. genInternalNonZeroValueIdx[i]++
  2124. idx := genInternalNonZeroValueIdx[i]
  2125. slen := uint64(len(genInternalNonZeroValueStrs))
  2126. return genInternalNonZeroValueStrs[idx%slen][i] // return string, to remove ambiguity
  2127. }
  2128. // Note: used for fastpath only
  2129. func genInternalEncCommandAsString(s string, vname string) string {
  2130. switch s {
  2131. case "uint64":
  2132. return "e.e.EncodeUint(" + vname + ")"
  2133. case "uint", "uint8", "uint16", "uint32":
  2134. return "e.e.EncodeUint(uint64(" + vname + "))"
  2135. case "int64":
  2136. return "e.e.EncodeInt(" + vname + ")"
  2137. case "int", "int8", "int16", "int32":
  2138. return "e.e.EncodeInt(int64(" + vname + "))"
  2139. case "[]byte", "[]uint8", "bytes":
  2140. return "e.e.EncodeStringBytesRaw(" + vname + ")"
  2141. case "string":
  2142. return "e.e.EncodeString(" + vname + ")"
  2143. case "float32":
  2144. return "e.e.EncodeFloat32(" + vname + ")"
  2145. case "float64":
  2146. return "e.e.EncodeFloat64(" + vname + ")"
  2147. case "bool":
  2148. return "e.e.EncodeBool(" + vname + ")"
  2149. // case "symbol":
  2150. // return "e.e.EncodeSymbol(" + vname + ")"
  2151. default:
  2152. return "e.encode(" + vname + ")"
  2153. }
  2154. }
  2155. // Note: used for fastpath only
  2156. func genInternalDecCommandAsString(s string, mapkey bool) string {
  2157. switch s {
  2158. case "uint":
  2159. return "uint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))"
  2160. case "uint8":
  2161. return "uint8(chkOvf.UintV(d.d.DecodeUint64(), 8))"
  2162. case "uint16":
  2163. return "uint16(chkOvf.UintV(d.d.DecodeUint64(), 16))"
  2164. case "uint32":
  2165. return "uint32(chkOvf.UintV(d.d.DecodeUint64(), 32))"
  2166. case "uint64":
  2167. return "d.d.DecodeUint64()"
  2168. case "uintptr":
  2169. return "uintptr(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))"
  2170. case "int":
  2171. return "int(chkOvf.IntV(d.d.DecodeInt64(), intBitsize))"
  2172. case "int8":
  2173. return "int8(chkOvf.IntV(d.d.DecodeInt64(), 8))"
  2174. case "int16":
  2175. return "int16(chkOvf.IntV(d.d.DecodeInt64(), 16))"
  2176. case "int32":
  2177. return "int32(chkOvf.IntV(d.d.DecodeInt64(), 32))"
  2178. case "int64":
  2179. return "d.d.DecodeInt64()"
  2180. case "string":
  2181. // if mapkey {
  2182. // return "d.stringZC(d.d.DecodeStringAsBytes())"
  2183. // }
  2184. // return "string(d.d.DecodeStringAsBytes())"
  2185. return "d.stringZC(d.d.DecodeStringAsBytes())"
  2186. case "[]byte", "[]uint8", "bytes":
  2187. return "d.d.DecodeBytes([]byte{})"
  2188. case "float32":
  2189. return "float32(d.decodeFloat32())"
  2190. case "float64":
  2191. return "d.d.DecodeFloat64()"
  2192. case "complex64":
  2193. return "complex(d.decodeFloat32(), 0)"
  2194. case "complex128":
  2195. return "complex(d.d.DecodeFloat64(), 0)"
  2196. case "bool":
  2197. return "d.d.DecodeBool()"
  2198. default:
  2199. halt.onerror(errors.New("gen internal: unknown type for decode: " + s))
  2200. }
  2201. return ""
  2202. }
  2203. // func genInternalSortType(s string, elem bool) string {
  2204. // for _, v := range [...]string{
  2205. // "int",
  2206. // "uint",
  2207. // "float",
  2208. // "bool",
  2209. // "string",
  2210. // "bytes", "[]uint8", "[]byte",
  2211. // } {
  2212. // if v == "[]byte" || v == "[]uint8" {
  2213. // v = "bytes"
  2214. // }
  2215. // if strings.HasPrefix(s, v) {
  2216. // if v == "int" || v == "uint" || v == "float" {
  2217. // v += "64"
  2218. // }
  2219. // if elem {
  2220. // return v
  2221. // }
  2222. // return v + "Slice"
  2223. // }
  2224. // }
  2225. // halt.onerror(errors.New("sorttype: unexpected type: " + s))
  2226. // }
  2227. func genInternalSortType(s string, elem bool) string {
  2228. if elem {
  2229. return s
  2230. }
  2231. return s + "Slice"
  2232. }
  2233. // MARKER: keep in sync with codecgen/gen.go
  2234. func genStripVendor(s string) string {
  2235. // HACK: Misbehaviour occurs in go 1.5. May have to re-visit this later.
  2236. // if s contains /vendor/ OR startsWith vendor/, then return everything after it.
  2237. const vendorStart = "vendor/"
  2238. const vendorInline = "/vendor/"
  2239. if i := strings.LastIndex(s, vendorInline); i >= 0 {
  2240. s = s[i+len(vendorInline):]
  2241. } else if strings.HasPrefix(s, vendorStart) {
  2242. s = s[len(vendorStart):]
  2243. }
  2244. return s
  2245. }
  2246. // var genInternalMu sync.Mutex
  2247. var genInternalV = genInternal{Version: genVersion}
  2248. var genInternalTmplFuncs template.FuncMap
  2249. var genInternalOnce sync.Once
  2250. func genInternalInit() {
  2251. wordSizeBytes := int(intBitsize) / 8
  2252. typesizes := map[string]int{
  2253. "interface{}": 2 * wordSizeBytes,
  2254. "string": 2 * wordSizeBytes,
  2255. "[]byte": 3 * wordSizeBytes,
  2256. "uint": 1 * wordSizeBytes,
  2257. "uint8": 1,
  2258. "uint16": 2,
  2259. "uint32": 4,
  2260. "uint64": 8,
  2261. "uintptr": 1 * wordSizeBytes,
  2262. "int": 1 * wordSizeBytes,
  2263. "int8": 1,
  2264. "int16": 2,
  2265. "int32": 4,
  2266. "int64": 8,
  2267. "float32": 4,
  2268. "float64": 8,
  2269. "complex64": 8,
  2270. "complex128": 16,
  2271. "bool": 1,
  2272. }
  2273. // keep as slice, so it is in specific iteration order.
  2274. // Initial order was uint64, string, interface{}, int, int64, ...
  2275. var types = [...]string{
  2276. "interface{}",
  2277. "string",
  2278. "[]byte",
  2279. "float32",
  2280. "float64",
  2281. "uint",
  2282. "uint8",
  2283. "uint16",
  2284. "uint32",
  2285. "uint64",
  2286. "uintptr",
  2287. "int",
  2288. "int8",
  2289. "int16",
  2290. "int32",
  2291. "int64",
  2292. "bool",
  2293. }
  2294. var primitivetypes, slicetypes, mapkeytypes, mapvaltypes []string
  2295. primitivetypes = types[:]
  2296. slicetypes = types[:]
  2297. mapkeytypes = types[:]
  2298. mapvaltypes = types[:]
  2299. if genFastpathTrimTypes {
  2300. // Note: we only create fast-paths for commonly used types.
  2301. // Consequently, things like int8, uint16, uint, etc are commented out.
  2302. slicetypes = genInternalFastpathSliceTypes()
  2303. mapkeytypes = genInternalFastpathMapKeyTypes()
  2304. mapvaltypes = genInternalFastpathMapValueTypes()
  2305. }
  2306. // var mapkeytypes [len(&types) - 1]string // skip bool
  2307. // copy(mapkeytypes[:], types[:])
  2308. // var mb []byte
  2309. // mb = append(mb, '|')
  2310. // for _, s := range mapkeytypes {
  2311. // mb = append(mb, s...)
  2312. // mb = append(mb, '|')
  2313. // }
  2314. // var mapkeytypestr = string(mb)
  2315. var gt = genInternal{Version: genVersion, Formats: genFormats}
  2316. // For each slice or map type, there must be a (symmetrical) Encode and Decode fast-path function
  2317. for _, s := range primitivetypes {
  2318. gt.Values = append(gt.Values,
  2319. fastpathGenV{Primitive: s, Size: typesizes[s], NoCanonical: !genFastpathCanonical})
  2320. }
  2321. for _, s := range slicetypes {
  2322. // if s != "uint8" { // do not generate fast path for slice of bytes. Treat specially already.
  2323. // gt.Values = append(gt.Values, fastpathGenV{Elem: s, Size: typesizes[s]})
  2324. // }
  2325. gt.Values = append(gt.Values,
  2326. fastpathGenV{Elem: s, Size: typesizes[s], NoCanonical: !genFastpathCanonical})
  2327. }
  2328. for _, s := range mapkeytypes {
  2329. // if _, ok := typesizes[s]; !ok {
  2330. // if strings.Contains(mapkeytypestr, "|"+s+"|") {
  2331. // gt.Values = append(gt.Values, fastpathGenV{MapKey: s, Elem: s, Size: 2 * typesizes[s]})
  2332. // }
  2333. for _, ms := range mapvaltypes {
  2334. gt.Values = append(gt.Values,
  2335. fastpathGenV{MapKey: s, Elem: ms, Size: typesizes[s] + typesizes[ms], NoCanonical: !genFastpathCanonical})
  2336. }
  2337. }
  2338. funcs := make(template.FuncMap)
  2339. // funcs["haspfx"] = strings.HasPrefix
  2340. funcs["encmd"] = genInternalEncCommandAsString
  2341. funcs["decmd"] = genInternalDecCommandAsString
  2342. funcs["zerocmd"] = genInternalZeroValue
  2343. funcs["nonzerocmd"] = genInternalNonZeroValue
  2344. funcs["hasprefix"] = strings.HasPrefix
  2345. funcs["sorttype"] = genInternalSortType
  2346. genInternalV = gt
  2347. genInternalTmplFuncs = funcs
  2348. }
  2349. // genInternalGoFile is used to generate source files from templates.
  2350. func genInternalGoFile(r io.Reader, w io.Writer) (err error) {
  2351. genInternalOnce.Do(genInternalInit)
  2352. gt := genInternalV
  2353. t := template.New("").Funcs(genInternalTmplFuncs)
  2354. tmplstr, err := ioutil.ReadAll(r)
  2355. if err != nil {
  2356. return
  2357. }
  2358. if t, err = t.Parse(string(tmplstr)); err != nil {
  2359. return
  2360. }
  2361. var out bytes.Buffer
  2362. err = t.Execute(&out, gt)
  2363. if err != nil {
  2364. return
  2365. }
  2366. bout, err := format.Source(out.Bytes())
  2367. if err != nil {
  2368. w.Write(out.Bytes()) // write out if error, so we can still see.
  2369. // w.Write(bout) // write out if error, as much as possible, so we can still see.
  2370. return
  2371. }
  2372. w.Write(bout)
  2373. return
  2374. }
  2375. func genInternalFastpathSliceTypes() []string {
  2376. return []string{
  2377. "interface{}",
  2378. "string",
  2379. "[]byte",
  2380. "float32",
  2381. "float64",
  2382. // "uint",
  2383. // "uint8", // no need for fastpath of []uint8, as it is handled specially
  2384. "uint8", // keep fast-path, so it doesn't have to go through reflection
  2385. // "uint16",
  2386. // "uint32",
  2387. "uint64",
  2388. // "uintptr",
  2389. "int",
  2390. // "int8",
  2391. // "int16",
  2392. "int32", // rune
  2393. "int64",
  2394. "bool",
  2395. }
  2396. }
  2397. func genInternalFastpathMapKeyTypes() []string {
  2398. return []string{
  2399. // "interface{}",
  2400. "string",
  2401. // "[]byte",
  2402. // "float32",
  2403. // "float64",
  2404. // "uint",
  2405. "uint8", // byte
  2406. // "uint16",
  2407. // "uint32",
  2408. "uint64", // used for keys
  2409. // "uintptr",
  2410. "int", // default number key
  2411. // "int8",
  2412. // "int16",
  2413. "int32", // rune
  2414. // "int64",
  2415. // "bool",
  2416. }
  2417. }
  2418. func genInternalFastpathMapValueTypes() []string {
  2419. return []string{
  2420. "interface{}",
  2421. "string",
  2422. "[]byte",
  2423. // "uint",
  2424. "uint8", // byte
  2425. // "uint16",
  2426. // "uint32",
  2427. "uint64", // used for keys, etc
  2428. // "uintptr",
  2429. "int", // default number
  2430. //"int8",
  2431. // "int16",
  2432. "int32", // rune (mostly used for unicode)
  2433. // "int64",
  2434. // "float32",
  2435. "float64",
  2436. "bool",
  2437. }
  2438. }
  2439. // sort-slice ...
  2440. // generates sort implementations for
  2441. // various slice types and combination slice+reflect.Value types.
  2442. //
  2443. // The combination slice+reflect.Value types are used
  2444. // during canonical encode, and the others are used during fast-path
  2445. // encoding of map keys.
  2446. // genInternalSortableTypes returns the types
  2447. // that are used for fast-path canonical's encoding of maps.
  2448. //
  2449. // For now, we only support the highest sizes for
  2450. // int64, uint64, float64, bool, string, bytes.
  2451. func genInternalSortableTypes() []string {
  2452. return genInternalFastpathMapKeyTypes()
  2453. }
  2454. // genInternalSortablePlusTypes returns the types
  2455. // that are used for reflection-based canonical's encoding of maps.
  2456. //
  2457. // For now, we only support the highest sizes for
  2458. // int64, uint64, float64, bool, string, bytes.
  2459. func genInternalSortablePlusTypes() []string {
  2460. return []string{
  2461. "string",
  2462. "float64",
  2463. "uint64",
  2464. // "uintptr",
  2465. "int64",
  2466. "bool",
  2467. "time",
  2468. "bytes",
  2469. }
  2470. }
  2471. func genTypeForShortName(s string) string {
  2472. switch s {
  2473. case "time":
  2474. return "time.Time"
  2475. case "bytes":
  2476. return "[]byte"
  2477. }
  2478. return s
  2479. }
  2480. func genArgs(args ...interface{}) map[string]interface{} {
  2481. m := make(map[string]interface{}, len(args)/2)
  2482. for i := 0; i < len(args); {
  2483. m[args[i].(string)] = args[i+1]
  2484. i += 2
  2485. }
  2486. return m
  2487. }
  2488. func genEndsWith(s0 string, sn ...string) bool {
  2489. for _, s := range sn {
  2490. if strings.HasSuffix(s0, s) {
  2491. return true
  2492. }
  2493. }
  2494. return false
  2495. }
  2496. func genCheckErr(err error) {
  2497. halt.onerror(err)
  2498. }
  2499. func genRunSortTmpl2Go(fnameIn, fnameOut string) {
  2500. var err error
  2501. funcs := make(template.FuncMap)
  2502. funcs["sortables"] = genInternalSortableTypes
  2503. funcs["sortablesplus"] = genInternalSortablePlusTypes
  2504. funcs["tshort"] = genTypeForShortName
  2505. funcs["endswith"] = genEndsWith
  2506. funcs["args"] = genArgs
  2507. t := template.New("").Funcs(funcs)
  2508. fin, err := os.Open(fnameIn)
  2509. genCheckErr(err)
  2510. defer fin.Close()
  2511. fout, err := os.Create(fnameOut)
  2512. genCheckErr(err)
  2513. defer fout.Close()
  2514. tmplstr, err := ioutil.ReadAll(fin)
  2515. genCheckErr(err)
  2516. t, err = t.Parse(string(tmplstr))
  2517. genCheckErr(err)
  2518. var out bytes.Buffer
  2519. err = t.Execute(&out, 0)
  2520. genCheckErr(err)
  2521. bout, err := format.Source(out.Bytes())
  2522. if err != nil {
  2523. fout.Write(out.Bytes()) // write out if error, so we can still see.
  2524. }
  2525. genCheckErr(err)
  2526. // write out if error, as much as possible, so we can still see.
  2527. _, err = fout.Write(bout)
  2528. genCheckErr(err)
  2529. }
  2530. func genRunTmpl2Go(fnameIn, fnameOut string) {
  2531. // println("____ " + fnameIn + " --> " + fnameOut + " ______")
  2532. fin, err := os.Open(fnameIn)
  2533. genCheckErr(err)
  2534. defer fin.Close()
  2535. fout, err := os.Create(fnameOut)
  2536. genCheckErr(err)
  2537. defer fout.Close()
  2538. err = genInternalGoFile(fin, fout)
  2539. genCheckErr(err)
  2540. }
  2541. // --- some methods here for other types, which are only used in codecgen
  2542. // depth returns number of valid nodes in the hierachy
  2543. func (path *structFieldInfoPathNode) root() *structFieldInfoPathNode {
  2544. TOP:
  2545. if path.parent != nil {
  2546. path = path.parent
  2547. goto TOP
  2548. }
  2549. return path
  2550. }
  2551. func (path *structFieldInfoPathNode) fullpath() (p []*structFieldInfoPathNode) {
  2552. // this method is mostly called by a command-line tool - it's not optimized, and that's ok.
  2553. // it shouldn't be used in typical runtime use - as it does unnecessary allocation.
  2554. d := path.depth()
  2555. p = make([]*structFieldInfoPathNode, d)
  2556. for d--; d >= 0; d-- {
  2557. p[d] = path
  2558. path = path.parent
  2559. }
  2560. return
  2561. }