github.com/ipld/go-ipld-prime@v0.21.0/schema/gen/go/mixins/kindTraits.go (about)

     1  package mixins
     2  
     3  import (
     4  	"io"
     5  
     6  	"github.com/ipld/go-ipld-prime/datamodel"
     7  )
     8  
     9  // kindTraitsGenerator is the center of all the other mixins,
    10  // and handles all the method generation which is a pure function of the kind.
    11  //
    12  // OVERRIDE THE METHODS THAT DO APPLY TO YOUR KIND;
    13  // the default method bodies produced by this mixin are those that return errors,
    14  // and that is not what you want for the methods that *are* interesting for your kind.
    15  // The kindTraitsGenerator methods will panic if called for a kind that should've overriden them.
    16  //
    17  // If you're implementing something that can hold "any" kind,
    18  // probably none of these methods apply to you at all.
    19  //
    20  // The other types in this package use kindTraitsGenerator with a fixed Kind,
    21  // and only forward the methods to it that don't apply for their kind;
    22  // this means when they're used as an anonymous embed, they grant
    23  // all the appropriate dummy methods to their container,
    24  // while leaving the ones that are still needed entirely absent,
    25  // so the compiler helpfully tells you to finish rather than waiting until
    26  // runtime to panic if a should-have-been-overriden method slips through.
    27  type kindTraitsGenerator struct {
    28  	PkgName    string
    29  	TypeName   string // as will be printed in messages (e.g. can be goosed up a bit, like "Thing.Repr" instead of "_Thing__Repr").
    30  	TypeSymbol string // the identifier in code (sometimes is munged internals like "_Thing__Repr" corresponding to no publicly admitted schema.Type.Name).
    31  	Kind       datamodel.Kind
    32  }
    33  
    34  func (g kindTraitsGenerator) emitNodeMethodLookupByString(w io.Writer) {
    35  	if datamodel.KindSet_JustMap.Contains(g.Kind) {
    36  		panic("gen internals error: you should've overriden this")
    37  	}
    38  	doTemplate(`
    39  		func ({{ .TypeSymbol }}) LookupByString(string) (datamodel.Node, error) {
    40  			return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.LookupByString("")
    41  		}
    42  	`, w, g)
    43  }
    44  
    45  func (g kindTraitsGenerator) emitNodeMethodLookupByNode(w io.Writer) {
    46  	if datamodel.KindSet_JustMap.Contains(g.Kind) {
    47  		panic("gen internals error: you should've overriden this")
    48  	}
    49  	doTemplate(`
    50  		func ({{ .TypeSymbol }}) LookupByNode(datamodel.Node) (datamodel.Node, error) {
    51  			return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.LookupByNode(nil)
    52  		}
    53  	`, w, g)
    54  }
    55  
    56  func (g kindTraitsGenerator) emitNodeMethodLookupByIndex(w io.Writer) {
    57  	if datamodel.KindSet_JustList.Contains(g.Kind) {
    58  		panic("gen internals error: you should've overriden this")
    59  	}
    60  	doTemplate(`
    61  		func ({{ .TypeSymbol }}) LookupByIndex(idx int64) (datamodel.Node, error) {
    62  			return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.LookupByIndex(0)
    63  		}
    64  	`, w, g)
    65  }
    66  
    67  func (g kindTraitsGenerator) emitNodeMethodLookupBySegment(w io.Writer) {
    68  	if datamodel.KindSet_Recursive.Contains(g.Kind) {
    69  		panic("gen internals error: you should've overriden this")
    70  	}
    71  	doTemplate(`
    72  		func ({{ .TypeSymbol }}) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) {
    73  			return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.LookupBySegment(seg)
    74  		}
    75  	`, w, g)
    76  }
    77  
    78  func (g kindTraitsGenerator) emitNodeMethodMapIterator(w io.Writer) {
    79  	if datamodel.KindSet_JustMap.Contains(g.Kind) {
    80  		panic("gen internals error: you should've overriden this")
    81  	}
    82  	doTemplate(`
    83  		func ({{ .TypeSymbol }}) MapIterator() datamodel.MapIterator {
    84  			return nil
    85  		}
    86  	`, w, g)
    87  }
    88  
    89  func (g kindTraitsGenerator) emitNodeMethodListIterator(w io.Writer) {
    90  	if datamodel.KindSet_JustList.Contains(g.Kind) {
    91  		panic("gen internals error: you should've overriden this")
    92  	}
    93  	doTemplate(`
    94  		func ({{ .TypeSymbol }}) ListIterator() datamodel.ListIterator {
    95  			return nil
    96  		}
    97  	`, w, g)
    98  }
    99  
   100  func (g kindTraitsGenerator) emitNodeMethodLength(w io.Writer) {
   101  	if datamodel.KindSet_Recursive.Contains(g.Kind) {
   102  		panic("gen internals error: you should've overriden this")
   103  	}
   104  	doTemplate(`
   105  		func ({{ .TypeSymbol }}) Length() int64 {
   106  			return -1
   107  		}
   108  	`, w, g)
   109  }
   110  
   111  func (g kindTraitsGenerator) emitNodeMethodIsAbsent(w io.Writer) {
   112  	doTemplate(`
   113  		func ({{ .TypeSymbol }}) IsAbsent() bool {
   114  			return false
   115  		}
   116  	`, w, g)
   117  }
   118  
   119  func (g kindTraitsGenerator) emitNodeMethodIsNull(w io.Writer) {
   120  	doTemplate(`
   121  		func ({{ .TypeSymbol }}) IsNull() bool {
   122  			return false
   123  		}
   124  	`, w, g)
   125  }
   126  
   127  func (g kindTraitsGenerator) emitNodeMethodAsBool(w io.Writer) {
   128  	if datamodel.KindSet_JustBool.Contains(g.Kind) {
   129  		panic("gen internals error: you should've overriden this")
   130  	}
   131  	doTemplate(`
   132  		func ({{ .TypeSymbol }}) AsBool() (bool, error) {
   133  			return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AsBool()
   134  		}
   135  	`, w, g)
   136  }
   137  
   138  func (g kindTraitsGenerator) emitNodeMethodAsInt(w io.Writer) {
   139  	if datamodel.KindSet_JustInt.Contains(g.Kind) {
   140  		panic("gen internals error: you should've overriden this")
   141  	}
   142  	doTemplate(`
   143  		func ({{ .TypeSymbol }}) AsInt() (int64, error) {
   144  			return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AsInt()
   145  		}
   146  	`, w, g)
   147  }
   148  
   149  func (g kindTraitsGenerator) emitNodeMethodAsFloat(w io.Writer) {
   150  	if datamodel.KindSet_JustFloat.Contains(g.Kind) {
   151  		panic("gen internals error: you should've overriden this")
   152  	}
   153  	doTemplate(`
   154  		func ({{ .TypeSymbol }}) AsFloat() (float64, error) {
   155  			return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AsFloat()
   156  		}
   157  	`, w, g)
   158  }
   159  
   160  func (g kindTraitsGenerator) emitNodeMethodAsString(w io.Writer) {
   161  	if datamodel.KindSet_JustString.Contains(g.Kind) {
   162  		panic("gen internals error: you should've overriden this")
   163  	}
   164  	doTemplate(`
   165  		func ({{ .TypeSymbol }}) AsString() (string, error) {
   166  			return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AsString()
   167  		}
   168  	`, w, g)
   169  }
   170  
   171  func (g kindTraitsGenerator) emitNodeMethodAsBytes(w io.Writer) {
   172  	if datamodel.KindSet_JustBytes.Contains(g.Kind) {
   173  		panic("gen internals error: you should've overriden this")
   174  	}
   175  	doTemplate(`
   176  		func ({{ .TypeSymbol }}) AsBytes() ([]byte, error) {
   177  			return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AsBytes()
   178  		}
   179  	`, w, g)
   180  }
   181  
   182  func (g kindTraitsGenerator) emitNodeMethodAsLink(w io.Writer) {
   183  	if datamodel.KindSet_JustLink.Contains(g.Kind) {
   184  		panic("gen internals error: you should've overriden this")
   185  	}
   186  	doTemplate(`
   187  		func ({{ .TypeSymbol }}) AsLink() (datamodel.Link, error) {
   188  			return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AsLink()
   189  		}
   190  	`, w, g)
   191  }
   192  
   193  // kindAssemblerTraitsGenerator is an awfully lot like kindTraitsGenerator,
   194  // except applying to methods for builders and assemblers.
   195  type kindAssemblerTraitsGenerator struct {
   196  	PkgName       string
   197  	TypeName      string // as will be printed in messages (e.g. can be goosed up a bit, like "Thing.Repr" instead of "_Thing__Repr").
   198  	AppliedPrefix string // the prefix of what to attach methods to... this one is a little wild: should probably be either "_{{ .Type | TypeSymbol }}__" or "_{{ .Type | TypeSymbol }}__Repr", and we'll just add the words "Builder" and "Assembler".
   199  	Kind          datamodel.Kind
   200  }
   201  
   202  // bailed on extracting a common emitNodeBuilderType: too many variations in content and pointer placement to be worth it.
   203  // bailed on extracting a common emitNodeBuilderMethods: same.
   204  // bailed on extracting a common emitNodeAssemblerType: same.
   205  //
   206  // If you try to do these, you'll probably need:
   207  //  - an explicit understanding of if generating representations or not
   208  //  - to still be ready for boatloads of exceptions if the representation isn't directly castable to and from the type-level node.
   209  
   210  func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodBeginMap(w io.Writer) {
   211  	if datamodel.KindSet_JustMap.Contains(g.Kind) {
   212  		panic("gen internals error: you should've overriden this")
   213  	}
   214  	doTemplate(`
   215  		func ({{ .AppliedPrefix }}Assembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) {
   216  			return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.BeginMap(0)
   217  		}
   218  	`, w, g)
   219  }
   220  
   221  func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodBeginList(w io.Writer) {
   222  	if datamodel.KindSet_JustList.Contains(g.Kind) {
   223  		panic("gen internals error: you should've overriden this")
   224  	}
   225  	doTemplate(`
   226  		func ({{ .AppliedPrefix }}Assembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) {
   227  			return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.BeginList(0)
   228  		}
   229  	`, w, g)
   230  }
   231  
   232  func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodAssignNull(w io.Writer) {
   233  	if datamodel.KindSet_JustNull.Contains(g.Kind) {
   234  		panic("gen internals error: you should've overriden this")
   235  	}
   236  	doTemplate(`
   237  		func (na *{{ .AppliedPrefix }}Assembler) AssignNull() error {
   238  			return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AssignNull()
   239  		}
   240  	`, w, g)
   241  }
   242  
   243  func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodAssignBool(w io.Writer) {
   244  	if datamodel.KindSet_JustBool.Contains(g.Kind) {
   245  		panic("gen internals error: you should've overriden this")
   246  	}
   247  	doTemplate(`
   248  		func ({{ .AppliedPrefix }}Assembler) AssignBool(bool) error {
   249  			return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AssignBool(false)
   250  		}
   251  	`, w, g)
   252  }
   253  
   254  func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodAssignInt(w io.Writer) {
   255  	if datamodel.KindSet_JustInt.Contains(g.Kind) {
   256  		panic("gen internals error: you should've overriden this")
   257  	}
   258  	doTemplate(`
   259  		func ({{ .AppliedPrefix }}Assembler) AssignInt(int64) error {
   260  			return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AssignInt(0)
   261  		}
   262  	`, w, g)
   263  }
   264  
   265  func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodAssignFloat(w io.Writer) {
   266  	if datamodel.KindSet_JustFloat.Contains(g.Kind) {
   267  		panic("gen internals error: you should've overriden this")
   268  	}
   269  	doTemplate(`
   270  		func ({{ .AppliedPrefix }}Assembler) AssignFloat(float64) error {
   271  			return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AssignFloat(0)
   272  		}
   273  	`, w, g)
   274  }
   275  
   276  func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodAssignString(w io.Writer) {
   277  	if datamodel.KindSet_JustString.Contains(g.Kind) {
   278  		panic("gen internals error: you should've overriden this")
   279  	}
   280  	doTemplate(`
   281  		func ({{ .AppliedPrefix }}Assembler) AssignString(string) error {
   282  			return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AssignString("")
   283  		}
   284  	`, w, g)
   285  }
   286  
   287  func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodAssignBytes(w io.Writer) {
   288  	if datamodel.KindSet_JustBytes.Contains(g.Kind) {
   289  		panic("gen internals error: you should've overriden this")
   290  	}
   291  	doTemplate(`
   292  		func ({{ .AppliedPrefix }}Assembler) AssignBytes([]byte) error {
   293  			return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AssignBytes(nil)
   294  		}
   295  	`, w, g)
   296  }
   297  
   298  func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodAssignLink(w io.Writer) {
   299  	if datamodel.KindSet_JustLink.Contains(g.Kind) {
   300  		panic("gen internals error: you should've overriden this")
   301  	}
   302  	doTemplate(`
   303  		func ({{ .AppliedPrefix }}Assembler) AssignLink(datamodel.Link) error {
   304  			return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AssignLink(nil)
   305  		}
   306  	`, w, g)
   307  }
   308  
   309  // bailed on extracting a common emitNodeAssemblerMethodAssignNode: way too many variations.
   310  
   311  func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodPrototype(w io.Writer) {
   312  	doTemplate(`
   313  		func ({{ .AppliedPrefix }}Assembler) Prototype() datamodel.NodePrototype {
   314  			return {{ .AppliedPrefix }}Prototype{}
   315  		}
   316  	`, w, g)
   317  }
   318  
   319  // bailed on extracting a common emitNodeAssemblerOtherBits: it's just self-evident there's nothing common there.