Skip to content

Commit

Permalink
schema: enable inline types through dsl parser & compiler (#404)
Browse files Browse the repository at this point in the history
  • Loading branch information
rvagg committed Apr 27, 2022
1 parent 7e37396 commit a6ca7b4
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 21 deletions.
74 changes: 61 additions & 13 deletions schema/dmt/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,23 +66,32 @@ func todoFromImplicitlyFalseBool(b *bool) bool {
return *b
}

func todoAnonTypeName(nameOrDefn TypeNameOrInlineDefn) string {
func anonTypeName(nameOrDefn TypeNameOrInlineDefn) string {
if nameOrDefn.TypeName != nil {
return *nameOrDefn.TypeName
}
defn := *nameOrDefn.InlineDefn
switch {
case defn.TypeDefnMap != nil:
defn := defn.TypeDefnMap
return fmt.Sprintf("Map__%s__%s", defn.KeyType, todoAnonTypeName(defn.ValueType))
return fmt.Sprintf("Map__%s__%s", defn.KeyType, anonTypeName(defn.ValueType))
case defn.TypeDefnList != nil:
defn := defn.TypeDefnList
return fmt.Sprintf("List__%s", todoAnonTypeName(defn.ValueType))
return fmt.Sprintf("List__%s", anonTypeName(defn.ValueType))
case defn.TypeDefnLink != nil:
return anonLinkName(*defn.TypeDefnLink)
default:
panic(fmt.Errorf("%#v", defn))
}
}

func anonLinkName(defn TypeDefnLink) string {
if defn.ExpectedType != nil {
return fmt.Sprintf("Link__%s", *defn.ExpectedType)
}
return "Link__Link"
}

func parseKind(s string) datamodel.Kind {
switch s {
case "map":
Expand Down Expand Up @@ -124,8 +133,20 @@ func spawnType(ts *schema.TypeSystem, name schema.TypeName, defn TypeDefn) (sche

case defn.TypeDefnList != nil:
typ := defn.TypeDefnList
if typ.ValueType.InlineDefn != nil {
return nil, fmt.Errorf("TODO: support anonymous types in schema package")
tname := ""
if typ.ValueType.TypeName != nil {
tname = *typ.ValueType.TypeName
} else if tname = anonTypeName(typ.ValueType); ts.TypeByName(tname) == nil {
anonDefn := TypeDefn{
TypeDefnMap: typ.ValueType.InlineDefn.TypeDefnMap,
TypeDefnList: typ.ValueType.InlineDefn.TypeDefnList,
TypeDefnLink: typ.ValueType.InlineDefn.TypeDefnLink,
}
anonType, err := spawnType(ts, tname, anonDefn)
if err != nil {
return nil, err
}
ts.Accumulate(anonType)
}
switch {
case typ.Representation == nil ||
Expand All @@ -135,13 +156,25 @@ func spawnType(ts *schema.TypeSystem, name schema.TypeName, defn TypeDefn) (sche
return nil, fmt.Errorf("TODO: support other list repr in schema package")
}
return schema.SpawnList(name,
*typ.ValueType.TypeName,
tname,
todoFromImplicitlyFalseBool(typ.ValueNullable),
), nil
case defn.TypeDefnMap != nil:
typ := defn.TypeDefnMap
if typ.ValueType.InlineDefn != nil {
return nil, fmt.Errorf("TODO: support anonymous types in schema package")
tname := ""
if typ.ValueType.TypeName != nil {
tname = *typ.ValueType.TypeName
} else if tname = anonTypeName(typ.ValueType); ts.TypeByName(tname) == nil {
anonDefn := TypeDefn{
TypeDefnMap: typ.ValueType.InlineDefn.TypeDefnMap,
TypeDefnList: typ.ValueType.InlineDefn.TypeDefnList,
TypeDefnLink: typ.ValueType.InlineDefn.TypeDefnLink,
}
anonType, err := spawnType(ts, tname, anonDefn)
if err != nil {
return nil, err
}
ts.Accumulate(anonType)
}
switch {
case typ.Representation == nil ||
Expand All @@ -154,7 +187,7 @@ func spawnType(ts *schema.TypeSystem, name schema.TypeName, defn TypeDefn) (sche
}
return schema.SpawnMap(name,
typ.KeyType,
*typ.ValueType.TypeName,
tname,
todoFromImplicitlyFalseBool(typ.ValueNullable),
), nil
case defn.TypeDefnStruct != nil:
Expand All @@ -165,7 +198,7 @@ func spawnType(ts *schema.TypeSystem, name schema.TypeName, defn TypeDefn) (sche
tname := ""
if field.Type.TypeName != nil {
tname = *field.Type.TypeName
} else if tname = todoAnonTypeName(field.Type); ts.TypeByName(tname) == nil {
} else if tname = anonTypeName(field.Type); ts.TypeByName(tname) == nil {
// Note that TypeDefn and InlineDefn aren't the same enum.
anonDefn := TypeDefn{
TypeDefnMap: field.Type.InlineDefn.TypeDefnMap,
Expand Down Expand Up @@ -243,7 +276,18 @@ func spawnType(ts *schema.TypeSystem, name schema.TypeName, defn TypeDefn) (sche
if member.TypeName != nil {
members = append(members, *member.TypeName)
} else {
panic("TODO: inline union members")
tname := anonLinkName(*member.UnionMemberInlineDefn.TypeDefnLink)
members = append(members, tname)
if ts.TypeByName(tname) == nil {
anonDefn := TypeDefn{
TypeDefnLink: member.UnionMemberInlineDefn.TypeDefnLink,
}
anonType, err := spawnType(ts, tname, anonDefn)
if err != nil {
return nil, err
}
ts.Accumulate(anonType)
}
}
}
remainingMembers := make(map[string]bool)
Expand Down Expand Up @@ -276,7 +320,9 @@ func spawnType(ts *schema.TypeSystem, name schema.TypeName, defn TypeDefn) (sche
validMember(memberName)
table[kind] = memberName
case member.UnionMemberInlineDefn != nil:
panic("TODO: inline defn support")
tname := anonLinkName(*member.UnionMemberInlineDefn.TypeDefnLink)
validMember(tname)
table[kind] = tname
}
}
repr = schema.SpawnUnionRepresentationKinded(table)
Expand All @@ -291,7 +337,9 @@ func spawnType(ts *schema.TypeSystem, name schema.TypeName, defn TypeDefn) (sche
validMember(memberName)
table[key] = memberName
case member.UnionMemberInlineDefn != nil:
panic("TODO: inline defn support")
tname := anonLinkName(*member.UnionMemberInlineDefn.TypeDefnLink)
validMember(tname)
table[key] = tname
}
}
repr = schema.SpawnUnionRepresentationKeyed(table)
Expand Down
22 changes: 16 additions & 6 deletions schema/dsl/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -478,11 +478,14 @@ func (p *parser) typeNameOrInlineDefn() (dmt.TypeNameOrInlineDefn, error) {
if err != nil {
return typ, err
}
if tok == "&" {
return typ, p.errf("TODO: links")
}

switch tok {
case "&":
expectedName, err := p.consumeName()
if err != nil {
return typ, err
}
typ.InlineDefn = &dmt.InlineDefn{TypeDefnLink: &dmt.TypeDefnLink{ExpectedType: &expectedName}}
case "[":
tlist, err := p.typeList()
if err != nil {
Expand Down Expand Up @@ -574,13 +577,20 @@ func (p *parser) typeUnion() (*dmt.TypeDefnUnion, error) {
return nil, p.errf("expected %q or %q, got %q", "}", "|", tok)
}
var member dmt.UnionMember
name, err := p.consumeName()
nameOrInline, err := p.typeNameOrInlineDefn()
if err != nil {
return nil, err
}
// TODO: inline defn
member.TypeName = &name

if nameOrInline.TypeName != nil {
member.TypeName = nameOrInline.TypeName
} else {
if nameOrInline.InlineDefn.TypeDefnLink != nil {
member.UnionMemberInlineDefn = &dmt.UnionMemberInlineDefn{TypeDefnLink: nameOrInline.InlineDefn.TypeDefnLink}
} else {
return nil, p.errf("expected a name or inline link, got neither")
}
}
defn.Members = append(defn.Members, member)

key, err := p.consumeToken()
Expand Down
2 changes: 1 addition & 1 deletion schema/gen/go/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func Generate(pth string, pkgName string, ts schema.TypeSystem, adjCfg *AdjunctC
panic("unrecognized union representation strategy")
}
default:
panic("add more type switches here :)")
panic(fmt.Sprintf("add more type switches here :), failed at type %s", tn))
}
}
}
Expand Down

0 comments on commit a6ca7b4

Please sign in to comment.