github.com/ipld/go-ipld-prime@v0.21.0/schema/gen/go/genListReprList.go (about) 1 package gengo 2 3 import ( 4 "io" 5 6 "github.com/ipld/go-ipld-prime/schema" 7 "github.com/ipld/go-ipld-prime/schema/gen/go/mixins" 8 ) 9 10 var _ TypeGenerator = &listReprListGenerator{} 11 12 func NewListReprListGenerator(pkgName string, typ *schema.TypeList, adjCfg *AdjunctCfg) TypeGenerator { 13 return listReprListGenerator{ 14 listGenerator{ 15 adjCfg, 16 mixins.ListTraits{ 17 PkgName: pkgName, 18 TypeName: string(typ.Name()), 19 TypeSymbol: adjCfg.TypeSymbol(typ), 20 }, 21 pkgName, 22 typ, 23 }, 24 } 25 } 26 27 type listReprListGenerator struct { 28 listGenerator 29 } 30 31 func (g listReprListGenerator) GetRepresentationNodeGen() NodeGenerator { 32 return listReprListReprGenerator{ 33 g.AdjCfg, 34 mixins.ListTraits{ 35 PkgName: g.PkgName, 36 TypeName: string(g.Type.Name()) + ".Repr", 37 TypeSymbol: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__Repr", 38 }, 39 g.PkgName, 40 g.Type, 41 } 42 } 43 44 type listReprListReprGenerator struct { 45 AdjCfg *AdjunctCfg 46 mixins.ListTraits 47 PkgName string 48 Type *schema.TypeList 49 } 50 51 func (listReprListReprGenerator) IsRepr() bool { return true } // hint used in some generalized templates. 52 53 func (g listReprListReprGenerator) EmitNodeType(w io.Writer) { 54 // Even though this is a "natural" representation... we need a new type here, 55 // because lists are recursive, and so all our functions that access 56 // children need to remember to return the representation node of those child values. 57 // It's still structurally the same, though (and we'll be able to cast in the methodset pattern). 58 // Error-thunking methods also have a different string in their error, so those are unique even if they don't seem particularly interesting. 59 doTemplate(` 60 type _{{ .Type | TypeSymbol }}__Repr _{{ .Type | TypeSymbol }} 61 `, w, g.AdjCfg, g) 62 } 63 64 func (g listReprListReprGenerator) EmitNodeTypeAssertions(w io.Writer) { 65 doTemplate(` 66 var _ datamodel.Node = &_{{ .Type | TypeSymbol }}__Repr{} 67 `, w, g.AdjCfg, g) 68 } 69 70 func (g listReprListReprGenerator) EmitNodeMethodLookupByNode(w io.Writer) { 71 // Null is also already a branch in the method we're calling; hopefully the compiler inlines and sees this and DTRT. 72 // REVIEW: these unchecked casts are definitely safe at compile time, but I'm not sure if the compiler considers that provable, 73 // so we should investigate if there's any runtime checks injected here that waste time. If so: write this with more gsloc to avoid :( 74 doTemplate(` 75 func (nr *_{{ .Type | TypeSymbol }}__Repr) LookupByNode(k datamodel.Node) (datamodel.Node, error) { 76 v, err := ({{ .Type | TypeSymbol }})(nr).LookupByNode(k) 77 if err != nil || v == datamodel.Null { 78 return v, err 79 } 80 return v.({{ .Type.ValueType | TypeSymbol}}).Representation(), nil 81 } 82 `, w, g.AdjCfg, g) 83 84 } 85 86 func (g listReprListReprGenerator) EmitNodeMethodLookupByIndex(w io.Writer) { 87 doTemplate(` 88 func (nr *_{{ .Type | TypeSymbol }}__Repr) LookupByIndex(idx int64) (datamodel.Node, error) { 89 v, err := ({{ .Type | TypeSymbol }})(nr).LookupByIndex(idx) 90 if err != nil || v == datamodel.Null { 91 return v, err 92 } 93 return v.({{ .Type.ValueType | TypeSymbol}}).Representation(), nil 94 } 95 `, w, g.AdjCfg, g) 96 } 97 98 func (g listReprListReprGenerator) EmitNodeMethodListIterator(w io.Writer) { 99 // FUTURE: trying to get this to share the preallocated memory if we get iterators wedged into their node slab will be ... fun. 100 doTemplate(` 101 func (nr *_{{ .Type | TypeSymbol }}__Repr) ListIterator() datamodel.ListIterator { 102 return &_{{ .Type | TypeSymbol }}__ReprListItr{({{ .Type | TypeSymbol }})(nr), 0} 103 } 104 105 type _{{ .Type | TypeSymbol }}__ReprListItr _{{ .Type | TypeSymbol }}__ListItr 106 107 func (itr *_{{ .Type | TypeSymbol }}__ReprListItr) Next() (idx int64, v datamodel.Node, err error) { 108 idx, v, err = (*_{{ .Type | TypeSymbol }}__ListItr)(itr).Next() 109 if err != nil || v == datamodel.Null { 110 return 111 } 112 return idx, v.({{ .Type.ValueType | TypeSymbol}}).Representation(), nil 113 } 114 func (itr *_{{ .Type | TypeSymbol }}__ReprListItr) Done() bool { 115 return (*_{{ .Type | TypeSymbol }}__ListItr)(itr).Done() 116 } 117 118 `, w, g.AdjCfg, g) 119 } 120 121 func (g listReprListReprGenerator) EmitNodeMethodLength(w io.Writer) { 122 doTemplate(` 123 func (rn *_{{ .Type | TypeSymbol }}__Repr) Length() int64 { 124 return int64(len(rn.x)) 125 } 126 `, w, g.AdjCfg, g) 127 } 128 129 func (g listReprListReprGenerator) EmitNodeMethodPrototype(w io.Writer) { 130 emitNodeMethodPrototype_typical(w, g.AdjCfg, g) 131 } 132 133 func (g listReprListReprGenerator) EmitNodePrototypeType(w io.Writer) { 134 emitNodePrototypeType_typical(w, g.AdjCfg, g) 135 } 136 137 // --- NodeBuilder and NodeAssembler ---> 138 139 func (g listReprListReprGenerator) GetNodeBuilderGenerator() NodeBuilderGenerator { 140 return listReprListReprBuilderGenerator{ 141 g.AdjCfg, 142 mixins.ListAssemblerTraits{ 143 PkgName: g.PkgName, 144 TypeName: g.TypeName, 145 AppliedPrefix: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__Repr", 146 }, 147 g.PkgName, 148 g.Type, 149 } 150 } 151 152 type listReprListReprBuilderGenerator struct { 153 AdjCfg *AdjunctCfg 154 mixins.ListAssemblerTraits 155 PkgName string 156 Type *schema.TypeList 157 } 158 159 func (listReprListReprBuilderGenerator) IsRepr() bool { return true } // hint used in some generalized templates. 160 161 func (g listReprListReprBuilderGenerator) EmitNodeBuilderType(w io.Writer) { 162 emitEmitNodeBuilderType_typical(w, g.AdjCfg, g) 163 } 164 func (g listReprListReprBuilderGenerator) EmitNodeBuilderMethods(w io.Writer) { 165 emitNodeBuilderMethods_typical(w, g.AdjCfg, g) 166 } 167 func (g listReprListReprBuilderGenerator) EmitNodeAssemblerType(w io.Writer) { 168 // - 'w' is the "**w**ip" pointer. 169 // - 'm' is the **m**aybe which communicates our completeness to the parent if we're a child assembler. 170 // - 'state' is what it says on the tin. this is used for the list state (the broad transitions between null, start-list, and finish are handled by 'm' for consistency with other types). 171 // 172 // - 'cm' is **c**hild **m**aybe and is used for the completion message from children. 173 // It's only present if list values *aren't* allowed to be nullable, since otherwise they have their own per-value maybe slot we can use. 174 // - 'va' is the embedded child value assembler. 175 // 176 // Note that this textually similar to the type-level assembler, but because it embeds the repr assembler for the child types, 177 // it might be *significantly* different in size and memory layout in that trailing part of the struct. 178 doTemplate(` 179 type _{{ .Type | TypeSymbol }}__ReprAssembler struct { 180 w *_{{ .Type | TypeSymbol }} 181 m *schema.Maybe 182 state laState 183 184 {{ if not .Type.ValueIsNullable }}cm schema.Maybe{{end}} 185 va _{{ .Type.ValueType | TypeSymbol }}__ReprAssembler 186 } 187 188 func (na *_{{ .Type | TypeSymbol }}__ReprAssembler) reset() { 189 na.state = laState_initial 190 na.va.reset() 191 } 192 `, w, g.AdjCfg, g) 193 } 194 func (g listReprListReprBuilderGenerator) EmitNodeAssemblerMethodBeginList(w io.Writer) { 195 emitNodeAssemblerMethodBeginList_listoid(w, g.AdjCfg, g) 196 } 197 func (g listReprListReprBuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) { 198 emitNodeAssemblerMethodAssignNull_recursive(w, g.AdjCfg, g) 199 } 200 func (g listReprListReprBuilderGenerator) EmitNodeAssemblerMethodAssignNode(w io.Writer) { 201 emitNodeAssemblerMethodAssignNode_listoid(w, g.AdjCfg, g) 202 } 203 func (g listReprListReprBuilderGenerator) EmitNodeAssemblerOtherBits(w io.Writer) { 204 emitNodeAssemblerHelper_listoid_tidyHelper(w, g.AdjCfg, g) 205 emitNodeAssemblerHelper_listoid_listAssemblerMethods(w, g.AdjCfg, g) 206 }