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  }