forked from ipld/go-ipld-prime
/
adjunctCfg.go
105 lines (92 loc) · 3.75 KB
/
adjunctCfg.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package gengo
import (
"fmt"
"strings"
"github.com/ipld/go-ipld-prime/schema"
)
// This entire file is placeholder-quality implementations.
//
// The AdjunctCfg struct should be replaced with an IPLD Schema-specified thing!
// The values in the unionMemlayout field should be an enum;
// etcetera!
type FieldTuple struct {
TypeName schema.TypeName
FieldName string
}
type AdjunctCfg struct {
typeSymbolOverrides map[schema.TypeName]string
FieldSymbolLowerOverrides map[FieldTuple]string
fieldSymbolUpperOverrides map[FieldTuple]string
maybeUsesPtr map[schema.TypeName]bool // treat absent as true
CfgUnionMemlayout map[schema.TypeName]string // "embedAll"|"interface"; maybe more options later, unclear for now.
// ... some of these fields have sprouted messy name prefixes so they don't collide with their matching method names.
// this structure has reached the critical threshhold where it due to be cleaned up and taken seriously.
// note: PkgName doesn't appear in here, because it's...
// not adjunct data. it's a generation invocation parameter.
// ... this might not hold up in the future though.
// There are unanswered questions about how (also, tbf, *if*) we'll handle generation of multiple packages which use each other's types.
}
// TypeSymbol returns the symbol for a type;
// by default, it's the same string as its name in the schema,
// but it can be overriden.
//
// This is the base, unembellished symbol.
// It's frequently augmented:
// prefixing an underscore to make it unexported;
// suffixing "__Something" to make the name of a supporting type;
// etc.
// (Most such augmentations are not configurable.)
func (cfg *AdjunctCfg) TypeSymbol(t schema.Type) string {
if x, ok := cfg.typeSymbolOverrides[t.Name()]; ok {
return x
}
return string(t.Name()) // presumed already upper
}
func (cfg *AdjunctCfg) FieldSymbolLower(f schema.StructField) string {
if x, ok := cfg.FieldSymbolLowerOverrides[FieldTuple{f.Parent().Name(), f.Name()}]; ok {
return x
}
return f.Name() // presumed already lower
}
func (cfg *AdjunctCfg) FieldSymbolUpper(f schema.StructField) string {
if x, ok := cfg.fieldSymbolUpperOverrides[FieldTuple{f.Type().Name(), f.Name()}]; ok {
return x
}
return strings.Title(f.Name())
}
// Comments returns a bool for whether comments should be included in gen output or not.
func (cfg *AdjunctCfg) Comments() bool {
return true // FUTURE: okay, maybe this should be configurable :)
}
func (cfg *AdjunctCfg) MaybeUsesPtr(t schema.Type) bool {
if x, ok := cfg.maybeUsesPtr[t.Name()]; ok {
return x
}
// FUTURE: we could make this default vary based on sizeof the type.
// It's generally true that for scalars it should be false by default; and that's easy to do.
// It would actually *remove* special cases from the prelude, which would be a win.
// Maps and lists should also probably default off...?
// (I have a feeling something might get touchy there. Review when implementing those.)
// Perhaps structs and unions are the only things likely to benefit from pointers.
return true
}
// UnionMemlayout returns a plain string at present;
// there's a case-switch in the templates that processes it.
// We validate that it's a known string when this method is called.
// This should probably be improved in type-safety,
// and validated more aggressively up front when adjcfg is loaded.
func (cfg *AdjunctCfg) UnionMemlayout(t schema.Type) string {
if t.TypeKind() != schema.TypeKind_Union {
panic(fmt.Errorf("%s is not a union!", t.Name()))
}
v, ok := cfg.CfgUnionMemlayout[t.Name()]
if !ok {
return "embedAll"
}
switch v {
case "embedAll", "interface":
return v
default:
panic(fmt.Errorf("invalid config: unionMemlayout values must be either \"embedAll\" or \"interface\", not %q", v))
}
}