Add initial convert (exp is broken at this commit)

Still need to flesh out the types for conversion. Also still need to add
the serialize and deserialize calls for individual types. Finally, will
need to put the finishing touches on writing the output files in the
desired directories. Then the experimental tool will be ready for end to
end testing.
このコミットが含まれているのは:
Cory Slep 2018-12-08 23:05:02 +01:00
コミット 069b8de820
8個のファイルの変更237行の追加27行の削除

209
tools/exp/convert/convert.go ノーマルファイル
ファイルの表示

@ -0,0 +1,209 @@
package convert
import (
"fmt"
"github.com/cjslep/activity/tools/exp/props"
"github.com/cjslep/activity/tools/exp/rdf"
"github.com/cjslep/activity/tools/exp/types"
"strings"
)
type vocabulary struct {
Kinds map[string]*props.Kind
FProps map[string]*props.FunctionalPropertyGenerator
NFProps map[string]*props.NonFunctionalPropertyGenerator
Types map[string]*types.TypeGenerator
}
func newVocabulary() vocabulary {
return vocabulary{
Kinds: make(map[string]*props.Kind, 0),
FProps: make(map[string]*props.FunctionalPropertyGenerator, 0),
NFProps: make(map[string]*props.NonFunctionalPropertyGenerator, 0),
Types: make(map[string]*types.TypeGenerator, 0),
}
}
type PropertyPackagePolicy int
const (
FlatUnderRoot PropertyPackagePolicy = iota
IndividualUnderRoot
)
type Converter struct {
Registry *rdf.RDFRegistry
VocabularyRoot string
PropertyPackagePolicy PropertyPackagePolicy
PropertyPackageRoot string
}
func (c Converter) convert(p *rdf.ParsedVocabulary) (v vocabulary, e error) {
v = newVocabulary()
for k, val := range p.Vocab.Values {
v.Kinds[k] = c.convertValue(val)
}
for k, prop := range p.Vocab.Properties {
if prop.Functional {
v.FProps[k], e = c.convertFunctionalProperty(prop, v.Kinds, p.Vocab, p.References)
} else {
v.NFProps[k], e = c.convertNonFunctionalProperty(prop, v.Kinds, p.Vocab, p.References)
}
if e != nil {
return
}
}
// TODO: Types in dependency order.
return
}
func (c Converter) convertFunctionalProperty(p rdf.VocabularyProperty,
kinds map[string]*props.Kind,
v rdf.Vocabulary,
refs map[string]*rdf.Vocabulary) (fp *props.FunctionalPropertyGenerator, e error) {
var k []props.Kind
k, e = c.propertyKinds(p, kinds, v, refs)
if e != nil {
return
}
var pkg string
pkg, e = c.propertyPackageName(p)
if e != nil {
return
}
fp = props.NewFunctionalPropertyGenerator(
pkg,
c.toIdentifier(p),
k,
p.NaturalLanguageMap)
return
}
func (c Converter) convertNonFunctionalProperty(p rdf.VocabularyProperty,
kinds map[string]*props.Kind,
v rdf.Vocabulary,
refs map[string]*rdf.Vocabulary) (nfp *props.NonFunctionalPropertyGenerator, e error) {
var k []props.Kind
k, e = c.propertyKinds(p, kinds, v, refs)
if e != nil {
return
}
var pkg string
pkg, e = c.propertyPackageName(p)
if e != nil {
return
}
nfp = props.NewNonFunctionalPropertyGenerator(
pkg,
c.toIdentifier(p),
k,
p.NaturalLanguageMap)
return
}
func (c Converter) convertValue(v rdf.VocabularyValue) (k *props.Kind) {
k = &props.Kind{
Name: c.toIdentifier(v),
ConcreteKind: v.DefinitionType,
Nilable: c.isNilable(v.DefinitionType),
SerializeFn: v.SerializeFn,
DeserializeFn: v.DeserializeFn,
LessFn: v.LessFn,
}
return
}
func (c Converter) convertTypeToKind(v rdf.VocabularyType) (k *props.Kind) {
k = &props.Kind{
Name: c.toIdentifier(v),
ConcreteKind: strings.Title(v.Name),
Nilable: true,
// TODO
SerializeFn: types.SerializeFn,
DeserializeFn: types.DeserializeFn,
LessFn: types.LessFn,
}
return
}
func (c Converter) propertyKinds(v rdf.VocabularyProperty,
kinds map[string]*props.Kind,
vocab rdf.Vocabulary,
refs map[string]*rdf.Vocabulary) (k []props.Kind, e error) {
for _, r := range v.Range {
if len(r.Vocab) == 0 {
if kind, ok := kinds[r.Name]; !ok {
// It is a Type of the vocabulary
if t, ok := vocab.Types[r.Name]; !ok {
e = fmt.Errorf("cannot find own kind with name %q", r.Name)
return
} else {
k = append(k, *c.convertTypeToKind(t))
}
} else {
// It is a Value of the vocabulary
k = append(k, *kind)
}
} else {
var url string
url, e = c.Registry.ResolveAlias(r.Vocab)
if e != nil {
return
}
refVocab, ok := refs[url]
if !ok {
e = fmt.Errorf("references do not contain %s", url)
return
}
if val, ok := refVocab.Values[r.Name]; !ok {
// It is a Type of the vocabulary instead
if t, ok := refVocab.Types[r.Name]; !ok {
e = fmt.Errorf("cannot find kind with name %q in %s", r.Name, url)
return
} else {
k = append(k, *c.convertTypeToKind(t))
}
} else {
// It is a Value of the vocabulary
k = append(k, *c.convertValue(val))
}
}
}
return
}
func (c Converter) propertyPackageName(v rdf.VocabularyProperty) (pkg string, e error) {
switch c.PropertyPackagePolicy {
case FlatUnderRoot:
pkg = c.PropertyPackageRoot
case IndividualUnderRoot:
pkg = v.Name
default:
e = fmt.Errorf("unrecognized PropertyPackagePolicy: %v", c.PropertyPackagePolicy)
}
return
}
// TODO: Use this?
func (c Converter) propertyPackageFile(v rdf.VocabularyProperty) (pkg string, e error) {
switch c.PropertyPackagePolicy {
case FlatUnderRoot:
pkg = fmt.Sprintf("%s/%s", c.VocabularyRoot, c.PropertyPackageRoot)
case IndividualUnderRoot:
pkg = fmt.Sprintf("%s/%s/%s", c.VocabularyRoot, c.PropertyPackageRoot, v.Name)
default:
e = fmt.Errorf("unrecognized PropertyPackagePolicy: %v", c.PropertyPackagePolicy)
}
return
}
func (c Converter) toIdentifier(n rdf.NameGetter) props.Identifier {
return props.Identifier{
LowerName: n.GetName(),
CamelName: strings.Title(n.GetName()),
}
}
func (c Converter) isNilable(goType string) bool {
return goType[0] == '*'
}

ファイルの表示

@ -2,8 +2,8 @@ package props
import (
"fmt"
"github.com/cjslep/activity/tools/exp/codegen"
"github.com/dave/jennifer/jen"
"github.com/go-fed/activity/tools/exp/codegen"
"sync"
)

ファイルの表示

@ -2,8 +2,8 @@ package props
import (
"fmt"
"github.com/cjslep/activity/tools/exp/codegen"
"github.com/dave/jennifer/jen"
"github.com/go-fed/activity/tools/exp/codegen"
"sync"
)

ファイルの表示

@ -2,8 +2,8 @@ package props
import (
"fmt"
"github.com/cjslep/activity/tools/exp/codegen"
"github.com/dave/jennifer/jen"
"github.com/go-fed/activity/tools/exp/codegen"
)
const (
@ -59,13 +59,12 @@ type Identifier struct {
// deserialize such types, compare the types, and other meta-information to use
// during Go code generation.
type Kind struct {
Name Identifier
ConcreteKind string
Nilable bool
HasNaturalLanguageMap bool
SerializeFn codegen.Function
DeserializeFn codegen.Function
LessFn codegen.Function
Name Identifier
ConcreteKind string
Nilable bool
SerializeFn codegen.Function
DeserializeFn codegen.Function
LessFn codegen.Function
}
// PropertyGenerator is a common base struct used in both Functional and

ファイルの表示

@ -3,6 +3,7 @@ package rdf
import (
"bytes"
"fmt"
"github.com/cjslep/activity/tools/exp/codegen"
"net/url"
)
@ -99,6 +100,9 @@ type VocabularyValue struct {
URI *url.URL
DefinitionType string
Zero string
SerializeFn codegen.Function
DeserializeFn codegen.Function
LessFn codegen.Function
}
func (v VocabularyValue) String() string {
@ -109,7 +113,7 @@ func (v *VocabularyValue) SetName(s string) {
v.Name = s
}
func (v *VocabularyValue) GetName() string {
func (v VocabularyValue) GetName() string {
return v.Name
}
@ -121,7 +125,7 @@ func (v *VocabularyValue) SetURI(s string) error {
var (
_ NameSetter = &VocabularyValue{}
_ nameGetter = &VocabularyValue{}
_ NameGetter = &VocabularyValue{}
_ URISetter = &VocabularyValue{}
)
@ -143,7 +147,7 @@ func (v *VocabularyType) SetName(s string) {
v.Name = s
}
func (v *VocabularyType) GetName() string {
func (v VocabularyType) GetName() string {
return v.Name
}
@ -163,7 +167,7 @@ func (v *VocabularyType) AddExample(e *VocabularyExample) {
var (
_ NameSetter = &VocabularyType{}
_ nameGetter = &VocabularyType{}
_ NameGetter = &VocabularyType{}
_ URISetter = &VocabularyType{}
_ NotesSetter = &VocabularyType{}
_ ExampleAdder = &VocabularyType{}
@ -193,7 +197,7 @@ func (v *VocabularyProperty) SetName(s string) {
v.Name = s
}
func (v *VocabularyProperty) GetName() string {
func (v VocabularyProperty) GetName() string {
return v.Name
}
@ -213,7 +217,7 @@ func (v *VocabularyProperty) AddExample(e *VocabularyExample) {
var (
_ NameSetter = &VocabularyProperty{}
_ nameGetter = &VocabularyProperty{}
_ NameGetter = &VocabularyProperty{}
_ URISetter = &VocabularyProperty{}
_ NotesSetter = &VocabularyProperty{}
_ ExampleAdder = &VocabularyProperty{}
@ -235,7 +239,7 @@ func (v *VocabularyExample) SetName(s string) {
v.Name = s
}
func (v *VocabularyExample) GetName() string {
func (v VocabularyExample) GetName() string {
return v.Name
}
@ -247,7 +251,7 @@ func (v *VocabularyExample) SetURI(s string) error {
var (
_ NameSetter = &VocabularyExample{}
_ nameGetter = &VocabularyExample{}
_ NameGetter = &VocabularyExample{}
_ URISetter = &VocabularyExample{}
)
@ -268,7 +272,7 @@ func (v *VocabularyReference) SetName(s string) {
v.Name = s
}
func (v *VocabularyReference) GetName() string {
func (v VocabularyReference) GetName() string {
return v.Name
}
@ -280,6 +284,6 @@ func (v *VocabularyReference) SetURI(s string) error {
var (
_ NameSetter = &VocabularyReference{}
_ nameGetter = &VocabularyReference{}
_ NameGetter = &VocabularyReference{}
_ URISetter = &VocabularyReference{}
)

ファイルの表示

@ -73,7 +73,7 @@ func (p *ParsingContext) Push() {
func (p *ParsingContext) Pop() {
p.Current = p.Stack[0]
p.Stack = p.Stack[1:]
if ng, ok := p.Current.(nameGetter); ok {
if ng, ok := p.Current.(NameGetter); ok {
p.Name = ng.GetName()
}
}
@ -92,7 +92,7 @@ type NameSetter interface {
SetName(string)
}
type nameGetter interface {
type NameGetter interface {
GetName() string
}
@ -194,7 +194,7 @@ func resolveReference(reference VocabularyReference, registry *RDFRegistry, ctx
vocab := &ctx.Result.Vocab
if len(reference.Vocab) > 0 {
name = joinAlias(reference.Vocab, reference.Name)
url, e := registry.resolveAlias(reference.Vocab)
url, e := registry.ResolveAlias(reference.Vocab)
if e != nil {
return e
}

ファイルの表示

@ -262,9 +262,7 @@ func (r *RDFRegistry) getNode(s string) (n RDFNode, e error) {
}
// resolveAlias turns an alias into its full qualifier for the ontology.
//
// Package public.
func (r *RDFRegistry) resolveAlias(alias string) (url string, e error) {
func (r *RDFRegistry) ResolveAlias(alias string) (url string, e error) {
var ok bool
if url, ok = r.aliases[alias]; !ok {
e = fmt.Errorf("registry cannot resolve alias %q", alias)

ファイルの表示

@ -2,8 +2,8 @@ package types
import (
"fmt"
"github.com/cjslep/activity/tools/exp/codegen"
"github.com/dave/jennifer/jen"
"github.com/go-fed/activity/tools/exp/codegen"
"sync"
)