From fe1e8a641a0495d615f6572e0189ddd16f511230 Mon Sep 17 00:00:00 2001 From: Joshua Watt Date: Fri, 1 Nov 2024 13:17:05 -0600 Subject: [PATCH] Initial golang implementation The initial implementation of the golang binding generation. This implementation is currently incomplete, as it is missing a few key features, namely: * Linking support And probably more, as well as many architectural problems However, this is implementation is sufficient to start getting feedback on the general structure of the bindings --- src/shacl2code/lang/__init__.py | 1 + src/shacl2code/lang/golang.py | 238 + src/shacl2code/lang/templates/golang.j2 | 1717 +++++++ testfixtures/jsonvalidation.py | 12 + tests/expect/golang/context/test-context.go | 4929 +++++++++++++++++++ tests/expect/golang/nocontext/test.go | 4900 ++++++++++++++++++ tests/expect/make_expect.py | 2 +- tests/test_golang.py | 873 ++++ 8 files changed, 12671 insertions(+), 1 deletion(-) create mode 100644 src/shacl2code/lang/golang.py create mode 100644 src/shacl2code/lang/templates/golang.j2 create mode 100644 tests/expect/golang/context/test-context.go create mode 100644 tests/expect/golang/nocontext/test.go create mode 100644 tests/test_golang.py diff --git a/src/shacl2code/lang/__init__.py b/src/shacl2code/lang/__init__.py index 76b2d89..5b6dad9 100644 --- a/src/shacl2code/lang/__init__.py +++ b/src/shacl2code/lang/__init__.py @@ -10,3 +10,4 @@ from .jinja import JinjaRender # noqa: F401 from .jsonschema import JsonSchemaRender # noqa: F401 from .python import PythonRender # noqa: F401 +from .golang import GoLangRender # noqa: F401 diff --git a/src/shacl2code/lang/golang.py b/src/shacl2code/lang/golang.py new file mode 100644 index 0000000..3f1c78a --- /dev/null +++ b/src/shacl2code/lang/golang.py @@ -0,0 +1,238 @@ +# +# Copyright (c) 2024 Joshua Watt +# +# SPDX-License-Identifier: MIT + +from .common import BasicJinjaRender +from .lang import language, TEMPLATE_DIR + +import re +import keyword + +GO_KEYWORDS = ( + "break", + "default", + "func", + "interface", + "select", + "case", + "defer", + "go", + "map", + "struct", + "chan", + "else", + "goto", + "package", + "switch", + "const", + "fallthrough", + "if", + "range", + "type", + "continue", + "for", + "import", + "return", + "var", +) + + +def varname(*name, public=True): + new_name = [] + for n in name: + for s in re.split(r"[^a-zA-Z0-9]+", n): + if not s: + continue + new_name.append(s) + if public: + new_name = [s[0].upper() + s[1:] for s in new_name] + else: + new_name = [new_name[0][0].lower() + new_name[0][1:]] + [ + s[0].upper() + s[1:] for s in new_name[1:] + ] + new_name = "".join(new_name) + if new_name in GO_KEYWORDS: + new_name = new_name + "_" + return new_name + + +def struct_name(cls): + return varname(*cls.clsname) + "Object" + + +def interface_name(cls): + return varname(*cls.clsname) + + +def class_type_var(cls): + return varname(*cls.clsname, public=False) + "Type" + + +def prop_name(prop): + return varname(prop.varname, public=False) + + +def prop_is_list(prop): + return prop.max_count is None or prop.max_count != 1 + + +def prop_go_type(prop, classes): + if prop.enum_values: + return "string" + + if prop.class_id: + intf = interface_name(classes.get(prop.class_id)) + return f"Ref[{intf}]" + + if prop.datatype == "http://www.w3.org/2001/XMLSchema#string": + return "string" + + if prop.datatype == "http://www.w3.org/2001/XMLSchema#anyURI": + return "string" + + if prop.datatype == "http://www.w3.org/2001/XMLSchema#integer": + return "int" + + if prop.datatype == "http://www.w3.org/2001/XMLSchema#positiveInteger": + return "int" + + if prop.datatype == "http://www.w3.org/2001/XMLSchema#nonNegativeInteger": + return "int" + + if prop.datatype == "http://www.w3.org/2001/XMLSchema#boolean": + return "bool" + + if prop.datatype == "http://www.w3.org/2001/XMLSchema#decimal": + return "float64" + + if prop.datatype == "http://www.w3.org/2001/XMLSchema#dateTime": + return "time.Time" + + if prop.datatype == "http://www.w3.org/2001/XMLSchema#dateTimeStamp": + return "time.Time" + + raise Exception("Unknown data type " + prop.datatype) # pragma: no cover + + +def prop_ctx_name(cls, prop): + return varname(*cls.clsname, public=False) + varname(prop.varname) + "Context" + + +def prop_decode_func(cls, prop, classes): + if prop.enum_values: + func = "DecodeIRI" + + elif prop.class_id: + func = "Decode" + interface_name(classes.get(prop.class_id)) + + elif prop.datatype == "http://www.w3.org/2001/XMLSchema#string": + func = "DecodeString" + + elif prop.datatype == "http://www.w3.org/2001/XMLSchema#anyURI": + func = "DecodeString" + + elif prop.datatype == "http://www.w3.org/2001/XMLSchema#integer": + func = "DecodeInteger" + + elif prop.datatype == "http://www.w3.org/2001/XMLSchema#positiveInteger": + func = "DecodeInteger" + + elif prop.datatype == "http://www.w3.org/2001/XMLSchema#nonNegativeInteger": + func = "DecodeInteger" + + elif prop.datatype == "http://www.w3.org/2001/XMLSchema#boolean": + func = "DecodeBoolean" + + elif prop.datatype == "http://www.w3.org/2001/XMLSchema#decimal": + func = "DecodeFloat" + + elif prop.datatype == "http://www.w3.org/2001/XMLSchema#dateTime": + func = "DecodeDateTime" + + elif prop.datatype == "http://www.w3.org/2001/XMLSchema#dateTimeStamp": + func = "DecodeDateTimeStamp" + + else: + raise Exception("Unknown data type " + prop.datatype) # pragma: no cover + + if prop_is_list(prop): + return f"DecodeList[{prop_go_type(prop, classes)}](value, path, {prop_ctx_name(cls, prop)}, {func})" + + return f"{func}(value, path, {prop_ctx_name(cls, prop)})" + + +def prop_encode_func(cls, prop, classes): + if prop.enum_values: + func = "EncodeIRI" + + elif prop.class_id: + func = "EncodeRef[" + interface_name(classes.get(prop.class_id)) + "]" + + elif prop.datatype == "http://www.w3.org/2001/XMLSchema#string": + func = "EncodeString" + + elif prop.datatype == "http://www.w3.org/2001/XMLSchema#anyURI": + func = "EncodeString" + + elif prop.datatype == "http://www.w3.org/2001/XMLSchema#integer": + func = "EncodeInteger" + + elif prop.datatype == "http://www.w3.org/2001/XMLSchema#positiveInteger": + func = "EncodeInteger" + + elif prop.datatype == "http://www.w3.org/2001/XMLSchema#nonNegativeInteger": + func = "EncodeInteger" + + elif prop.datatype == "http://www.w3.org/2001/XMLSchema#boolean": + func = "EncodeBoolean" + + elif prop.datatype == "http://www.w3.org/2001/XMLSchema#decimal": + func = "EncodeFloat" + + elif prop.datatype == "http://www.w3.org/2001/XMLSchema#dateTime": + func = "EncodeDateTime" + + elif prop.datatype == "http://www.w3.org/2001/XMLSchema#dateTimeStamp": + func = "EncodeDateTime" + + else: + raise Exception("Unknown data type " + prop.datatype) # pragma: no cover + + if prop_is_list(prop): + return f'EncodeList[{prop_go_type(prop, classes)}](self.{prop_name(prop)}.Get(), path.PushPath("{prop_name(prop)}"), {prop_ctx_name(cls, prop)}, state, {func})' + + return f'{func}(self.{prop_name(prop)}.Get(), path.PushPath("{prop_name(prop)}"), {prop_ctx_name(cls, prop)}, state)' + + +@language("golang") +class GoLangRender(BasicJinjaRender): + HELP = "Go Schema" + + def __init__(self, args): + super().__init__(args, TEMPLATE_DIR / "golang.j2") + self.__render_args = { + "package": args.package, + } + + @classmethod + def get_arguments(cls, parser): + super().get_arguments(parser) + parser.add_argument("-p", "--package", help="Go Package Name", default="model") + + def get_extra_env(self): + return { + "varname": varname, + "struct_name": struct_name, + "interface_name": interface_name, + "class_type_var": class_type_var, + "prop_name": prop_name, + "prop_is_list": prop_is_list, + "prop_go_type": prop_go_type, + "prop_ctx_name": prop_ctx_name, + "prop_decode_func": prop_decode_func, + "prop_encode_func": prop_encode_func, + } + + def get_additional_render_args(self): + return self.__render_args diff --git a/src/shacl2code/lang/templates/golang.j2 b/src/shacl2code/lang/templates/golang.j2 new file mode 100644 index 0000000..6f5892f --- /dev/null +++ b/src/shacl2code/lang/templates/golang.j2 @@ -0,0 +1,1717 @@ +// +//{# +vim: ft=go +#} +// + +package {{ package }} + +import ( + "encoding/json" + "fmt" + "reflect" + "regexp" + "sort" + "strconv" + "strings" + "time" + + "github.com/ncruces/go-strftime" +) + +// Validation Error +type ValidationError struct { + Property string + Err string +} + +func (e *ValidationError) Error() string { return e.Property + ": " + e.Err } + +// Conversion Error +type ConversionError struct { + From string + To string +} + +func (e *ConversionError) Error() string { + return "Unable to convert from " + e.From + " to " + e.To +} + +// Decode Error +type DecodeError struct { + Path Path + Err string +} + +func (e *DecodeError) Error() string { + return e.Path.ToString() + ": " + e.Err +} + +type EncodeError struct { + Path Path + Err string +} + +func (e *EncodeError) Error() string { + return e.Path.ToString() + ": " + e.Err +} + +// Path +type Path struct { + Path []string +} + +func (p *Path) PushPath(s string) Path { + new_p := *p + new_p.Path = append(new_p.Path, s) + return new_p +} + +func (p *Path) PushIndex(idx int) Path { + return p.PushPath("[" + strconv.Itoa(idx) + "]") +} + +func (p *Path) ToString() string { + return "." + strings.Join(p.Path, ".") +} + +// Error Handler +type ErrorHandler interface { + HandleError(error, Path) +} + +// Reference +type Ref[T SHACLObject] interface { + GetIRI() string + GetObj() T + IsSet() bool + IsObj() bool + IsIRI() bool +} + +type ref[T SHACLObject] struct { + obj *T + iri string +} + +func (r ref[T]) GetIRI() string { + if r.iri != "" { + return r.iri + } + if r.obj != nil { + o := *r.obj + if o.ID().IsSet() { + return o.ID().Get() + } + } + return "" +} + +func (r ref[T]) GetObj() T { + return *r.obj +} + +func (r ref[T]) IsSet() bool { return r.IsIRI() || r.IsObj() } +func (r ref[T]) IsObj() bool { return r.obj != nil } +func (r ref[T]) IsIRI() bool { return r.iri != "" } + +func MakeObjectRef[T SHACLObject](obj T) Ref[T] { + return ref[T]{&obj, ""} +} + +func MakeIRIRef[T SHACLObject](iri string) Ref[T] { + return ref[T]{nil, iri} +} + +// Convert one reference to another. Note that the output type is first so it +// can be specified, while the input type is generally inferred from the argument +func ConvertRef[TO SHACLObject, FROM SHACLObject](in Ref[FROM]) (Ref[TO], error) { + if in.IsObj() { + out_obj, ok := any(in.GetObj()).(TO) + if !ok { + return nil, &ConversionError{reflect.TypeOf(ref[FROM]{}).Name(), reflect.TypeOf(ref[TO]{}).Name()} + } + return ref[TO]{&out_obj, in.GetIRI()}, nil + } + return ref[TO]{nil, in.GetIRI()}, nil +} + +type Visit func(Path, any) + +// Base SHACL Object +type SHACLObjectBase struct { + // Object ID + id Property[string] + typ SHACLType + typeIRI string +} + +func (self *SHACLObjectBase) ID() PropertyInterface[string] { return &self.id } + +func (self *SHACLObjectBase) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + + switch self.typ.GetNodeKind() { + case NodeKindBlankNode: + if self.ID().IsSet() && ! IsBlankNode(self.ID().Get()) { + handler.HandleError(&ValidationError{ + "id", + "ID must by be blank node"}, + path.PushPath("id")) + valid = false + } + case NodeKindIRI: + if ! self.ID().IsSet() || ! IsIRI(self.ID().Get()) { + handler.HandleError(&ValidationError{ + "id", + "ID must be an IRI"}, + path.PushPath("id")) + valid = false + } + case NodeKindBlankNodeOrIRI: + if self.ID().IsSet() && ! IsBlankNode(self.ID().Get()) && ! IsIRI(self.ID().Get()) { + handler.HandleError(&ValidationError{ + "id", + "ID must be a blank node or IRI"}, + path.PushPath("id")) + valid = false + } + default: + panic("Unknown node kind") + } + + return valid +} + +func (self *SHACLObjectBase) Walk(path Path, visit Visit) { + self.id.Walk(path, visit) +} + +func (self *SHACLObjectBase) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if self.typeIRI != "" { + data["{{ context.compact_iri('@type') }}"] = self.typeIRI + } else { + data["{{ context.compact_iri('@type') }}"] = self.typ.GetCompactTypeIRI().GetDefault(self.typ.GetTypeIRI()) + } + + id_prop := self.typ.GetIDAlias().GetDefault("@id") + + if self.id.IsSet() { + val, err := EncodeIRI(self.id.Get(), path.PushPath(id_prop), map[string]string{}, state) + if err != nil { + return err + } + data[id_prop] = val + } + + return nil +} + +func (self *SHACLObjectBase) GetType() SHACLType { + return self.typ +} + +func (self *SHACLObjectBase) setTypeIRI(iri string) { + self.typeIRI = iri +} + +func ConstructSHACLObjectBase(o *SHACLObjectBase, typ SHACLType) *SHACLObjectBase { + o.id = NewProperty[string]("id", []Validator[string]{ IDValidator{}, }) + o.typ = typ + return o +} + +type SHACLObject interface { + ID() PropertyInterface[string] + Validate(path Path, handler ErrorHandler) bool + Walk(path Path, visit Visit) + EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error + GetType() SHACLType + setTypeIRI(iri string) +} + +func EncodeSHACLObject(o SHACLObject, path Path, state *EncodeState) (any, error) { + if state != nil { + if state.Written[o] { + if o.ID().IsSet() { + return o.ID().Get(), nil + } + + return nil, &EncodeError{ + path, + "Object referenced multiple times, but does not have an ID assigned", + } + } + + state.Written[o] = true + } + + d := make(map[string]interface{}) + return d, o.EncodeProperties(d, path, state) +} + +// Extensible Object + +type SHACLExtensibleBase struct { + properties map[string][]any +} + +func (self *SHACLExtensibleBase) GetExtProperty(name string) []any { + return self.properties[name] +} + +func (self *SHACLExtensibleBase) SetExtProperty(name string, value []any) { + if self.properties == nil { + self.properties = make(map[string][]any) + } + self.properties[name] = value +} + +func (self *SHACLExtensibleBase) DeleteExtProperty(name string) { + delete(self.properties, name) +} + +func (self *SHACLExtensibleBase) EncodeExtProperties(data map[string]any, path Path) error { + for k, values := range self.properties { + if len(values) == 0 { + continue + } + + lst := []any{} + for _, v := range values { + lst = append(lst, v) + } + data[k] = lst + } + return nil +} + +type SHACLExtensibleObject interface { + GetExtProperty(string) []any + SetExtProperty(string, []any) + DeleteExtProperty(string) +} + +// Type Metadata +const NodeKindBlankNode = 0 +const NodeKindIRI = 1 +const NodeKindBlankNodeOrIRI = 2 + +type SHACLType interface { + GetTypeIRI() string + GetCompactTypeIRI() Optional[string] + GetNodeKind() int + GetIDAlias() Optional[string] + DecodeProperty(SHACLObject, string, interface{}, Path) (bool, error) + Create() SHACLObject + IsAbstract() bool + IsExtensible() bool + IsSubClassOf(SHACLType) bool +} + +type SHACLTypeBase struct { + typeIRI string + compactTypeIRI Optional[string] + idAlias Optional[string] + isExtensible Optional[bool] + isAbstract bool + parentIRIs []string + nodeKind Optional[int] +} + +func (self SHACLTypeBase) GetTypeIRI() string { + return self.typeIRI +} + +func (self SHACLTypeBase) GetCompactTypeIRI() Optional[string] { + return self.compactTypeIRI +} + +func (self SHACLTypeBase) GetNodeKind() int { + if self.nodeKind.IsSet() { + return self.nodeKind.Get() + } + + for _, parent_id := range(self.parentIRIs) { + p := objectTypes[parent_id] + return p.GetNodeKind() + } + + return NodeKindBlankNodeOrIRI +} + +func (self SHACLTypeBase) GetIDAlias() Optional[string] { + if self.idAlias.IsSet() { + return self.idAlias + } + + for _, parent_id := range(self.parentIRIs) { + p := objectTypes[parent_id] + a := p.GetIDAlias() + if a.IsSet() { + return a + } + } + + return self.idAlias +} + +func (self SHACLTypeBase) IsAbstract() bool { + return self.isAbstract +} + +func (self SHACLTypeBase) IsExtensible() bool { + if self.isExtensible.IsSet() { + return self.isExtensible.Get() + } + + for _, parent_id := range(self.parentIRIs) { + p := objectTypes[parent_id] + if p.IsExtensible() { + return true + } + } + + return false +} + +func (self SHACLTypeBase) IsSubClassOf(other SHACLType) bool { + if other.GetTypeIRI() == self.typeIRI { + return true + } + + for _, parent_id := range(self.parentIRIs) { + p := objectTypes[parent_id] + if p.IsSubClassOf(other) { + return true + } + } + + return false +} + +type EncodeState struct { + Written map[SHACLObject]bool +} + +func (self SHACLTypeBase) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + id_alias := self.GetIDAlias() + if id_alias.IsSet() { + switch name { + case id_alias.Get(): + val, err := DecodeString(value, path.PushPath(name), map[string]string{}) + if err != nil { + return false, err + } + err = o.ID().Set(val) + if err != nil { + return false, err + } + return true, nil + case "@id": + return true, &DecodeError{ + path.PushPath(name), + "'@id' is not allowed for " + self.GetTypeIRI() + " which has an ID alias", + } + } + } else if name == "@id" { + val, err := DecodeString(value, path.PushPath(name), map[string]string{}) + if err != nil { + return false, err + } + err = o.ID().Set(val) + if err != nil { + return false, err + } + return true, nil + } + + for _, parent_id := range(self.parentIRIs) { + p := objectTypes[parent_id] + found, err := p.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + if self.isExtensible.GetDefault(false) { + obj := o.(SHACLExtensibleObject) + v, err := DecodeAny(value, path, map[string]string{}) + if err != nil { + return false, err + } + + lst, is_list := v.([]interface{}) + if is_list { + obj.SetExtProperty(name, lst) + } else { + obj.SetExtProperty(name, []interface{}{v}) + } + return true, nil + } + return false, nil +} + + +var objectTypes map[string] SHACLType + +func RegisterType(typ SHACLType) { + objectTypes[typ.GetTypeIRI()] = typ + compact := typ.GetCompactTypeIRI() + if compact.IsSet() { + objectTypes[compact.Get()] = typ + } +} + +// SHACLObjectSet +type SHACLObjectSet interface { + AddObject(r SHACLObject) + Decode(decoder *json.Decoder) error + Encode(encoder *json.Encoder) error + Walk(visit Visit) + Validate(handler ErrorHandler) bool +} + +type SHACLObjectSetObject struct { + objects []SHACLObject +} + +func (self *SHACLObjectSetObject) AddObject(r SHACLObject) { + self.objects = append(self.objects, r) +} + +func (self *SHACLObjectSetObject) Decode(decoder *json.Decoder) error { + path := Path{} + + var data map[string]interface{} + if err := decoder.Decode(&data); err != nil { + return err + } + + { + v, ok := data["@context"] + if ! ok { + return &DecodeError{path, "@context missing"} + } + + sub_path := path.PushPath("@context") + value, ok := v.(string) + if ! ok { + return &DecodeError{sub_path, "@context must be a string, or list of string"} + } + if value != "{{ context.urls[0] }}" { + return &DecodeError{sub_path, "Wrong context URL '" + value + "'"} + } + } + + delete(data, "@context") + + decodeProxy := func (data any, path Path, context map[string]string) (SHACLObject, error) { + return DecodeSHACLObject[SHACLObject](data, path, context, nil) + } + + _, has_graph := data["@graph"] + if has_graph { + for k, v := range data { + switch k { + case "@graph": { + objs, err := DecodeList[SHACLObject]( + v, + path.PushPath("@graph"), + map[string]string{}, + decodeProxy, + ) + + if err != nil { + return err + } + + for _, obj := range objs { + self.AddObject(obj) + } + } + + default: + return &DecodeError{path, "Unknown property '" + k + "'"} + } + } + } else { + obj, err := decodeProxy(data, path, map[string]string{}) + if err != nil { + return err + } + + self.AddObject(obj) + } + + return nil +} + +func (self *SHACLObjectSetObject) Encode(encoder *json.Encoder) error { + data := make(map[string]interface{}) +{%- if context.urls | length > 1 %} + data["@context"] = []string{ + {%- for url in context.urls %} + "{{ url }}", + {%- endfor %} + } +{%- else %} + data["@context"] = "{{ context.urls[0] }}" +{%- endif %} + path := Path{} + state := EncodeState{ + Written: make(map[SHACLObject]bool), + } + + ref_counts := make(map[SHACLObject]int) + + visit := func (path Path, v any) { + r, ok := v.(Ref[SHACLObject]) + if ! ok { + return + } + + if ! r.IsObj() { + return + } + + o := r.GetObj() + + // Remove blank nodes for reassignment + if o.ID().IsSet() && IsBlankNode(o.ID().Get()) { + o.ID().Delete() + } + + ref_counts[o] = ref_counts[o] + 1 + } + + self.Walk(visit) + + blank_count := 0 + for o, count := range ref_counts { + if count <= 1 { + continue + } + + if o.ID().IsSet() { + continue + } + + o.ID().Set(fmt.Sprintf("_:%d", blank_count)) + blank_count += 1 + } + + if len(self.objects) == 1 { + err := self.objects[0].EncodeProperties(data, path, &state) + if err != nil { + return err + } + } else if len(self.objects) > 1 { + // All objects directly added to the object set should be written as + // top level objects, so mark then as written until they are ready to + // be serialized, which will force them to be referenced by IRI until + // we are ready + for _, o := range self.objects { + state.Written[o] = true + } + + graph_path := path.PushPath("@graph") + lst := []interface{}{} + for idx, o := range self.objects { + // Remove this object from the written set now so it gets serialized + delete(state.Written, o) + + d, err := EncodeSHACLObject(o, graph_path.PushIndex(idx), &state) + if err != nil { + return err + } + lst = append(lst, d) + } + + data["@graph"] = lst + } + + return encoder.Encode(data) +} + +func (self *SHACLObjectSetObject) Walk(visit Visit) { + path := Path{} + visited := map[SHACLObject]bool{} + + visit_proxy := func (path Path, v any) { + switch v.(type) { + case Ref[SHACLObject]: + r := v.(Ref[SHACLObject]) + if ! r.IsObj() { + visit(path, v) + return + } + + o := r.GetObj() + _, ok := visited[o] + if ok { + return + } + visited[o] = true + visit(path, v) + o.Walk(path, visit) + return + + default: + visit(path, v) + return + } + } + + for idx, o := range(self.objects) { + sub_path := path.PushIndex(idx) + visit_proxy(sub_path, MakeObjectRef(o)) + } +} + +func (self *SHACLObjectSetObject) Validate(handler ErrorHandler) bool { + valid := true + + visit_proxy := func (path Path, v any) { + r, ok := v.(Ref[SHACLObject]) + if ! ok { + return + } + + if ! r.IsObj() { + return + } + + if ! r.GetObj().Validate(path, handler) { + valid = false + } + } + + self.Walk(visit_proxy) + + return valid +} + +func NewSHACLObjectSet() SHACLObjectSet { + os := SHACLObjectSetObject{} + return &os +} + +func DecodeAny(data any, path Path, context map[string]string) (any, error) { + switch data.(type) { + case map[string]interface{}: + return DecodeRef[SHACLObject](data, path, context, nil) + case string: + return DecodeString(data, path, context) + case int: + return DecodeInteger(data, path, context) + case float64: + return DecodeFloat(data, path, context) + case bool: + return DecodeBoolean(data, path, context) + case []interface{}: + return DecodeList[any](data, path, context, DecodeAny) + default: + return nil, &DecodeError{path, "Unknown type "+ reflect.TypeOf(data).Name()} + } +} + +func DecodeSHACLObject[T SHACLObject](data any, path Path, context map[string]string, targetType SHACLType) (T, error) { + dict, ok := data.(map[string]interface{}) + if ! ok { + return *new(T), &DecodeError{path, "Expected dictionary or string. Got " + reflect.TypeOf(data).Name()} + } + + var v interface{} + v, ok = dict["@type"] + if ! ok { + v, ok = dict["{{ context.compact_iri('@type') }}"] + if ! ok { + return *new(T), &DecodeError{path, "type missing"} + } + } + + var type_iri string + var create_type SHACLType + + type_iri, ok = v.(string) + if ! ok { + return *new(T), &DecodeError{path, "Wrong type for @type. Got " + reflect.TypeOf(v).Name()} + } + + iri_typ, ok := objectTypes[type_iri] + if ok { + if targetType != nil && !iri_typ.IsSubClassOf(targetType) { + return *new(T), &DecodeError{path, "Type " + type_iri + " is not valid where " + + targetType.GetTypeIRI() + " is expected"} + } + + if iri_typ.IsAbstract() { + return *new(T), &DecodeError{path, "Unable to create abstract type '" + type_iri + "'"} + } + + create_type = iri_typ + } else if targetType != nil && targetType.IsExtensible() { + // An extensible type is expected, so make one of the correct type + // + // Note: An abstract extensible class is actually allowed to be created + // here + create_type = targetType + } else { + if IsIRI(type_iri) { + // It's not clear exactly which type should be created. Search through + // all types and collect a list of possible Extensible types that are + // valid in this location. + possible := []SHACLType{} + for _, v := range objectTypes { + if ! v.IsExtensible() { + continue + } + + if v.IsAbstract() { + continue + } + + // If a type was specified, only subclasses of that type are + // allowed + if targetType != nil && ! v.IsSubClassOf(targetType) { + continue + } + + possible = append(possible, v) + } + + // Sort for determinism + sort.Slice(possible, func(i, j int) bool { + return possible[i].GetTypeIRI() < possible[j].GetTypeIRI() + }) + + for _, t := range(possible) { + // Ignore errors + o, err := DecodeSHACLObject[T](data, path, context, t) + if err == nil { + o.setTypeIRI(type_iri) + return o, nil + } + } + } + return *new(T), &DecodeError{path, "Unable to create object of type '" + type_iri + "' (no matching extensible object)"} + } + + obj, ok := create_type.Create().(T) + if ! ok { + return *new(T), &DecodeError{path, "Unable to create object of type '" + type_iri + "'"} + } + obj.setTypeIRI(type_iri) + + for k, v := range dict { + if k == "@type" { + continue + } + if k == "{{ context.compact_iri('@type') }}" { + continue + } + + sub_path := path.PushPath(k) + found, err := create_type.DecodeProperty(obj, k, v, sub_path) + if err != nil { + return *new(T), err + } + if ! found { + return *new(T), &DecodeError{path, "Unknown property '" + k + "'"} + } + } + + return obj, nil +} + +func DecodeRef[T SHACLObject](data any, path Path, context map[string]string, typ SHACLType) (Ref[T], error) { + switch data.(type) { + case string: + s, err := DecodeIRI(data, path, context) + if err != nil { + return nil, err + } + return MakeIRIRef[T](s), nil + } + + obj, err := DecodeSHACLObject[T](data, path, context, typ) + if err != nil { + return nil, err + } + + return MakeObjectRef[T](obj), nil +} + +func EncodeRef[T SHACLObject](value Ref[T], path Path, context map[string]string, state *EncodeState) (any, error) { + if value.IsIRI() { + v := value.GetIRI() + compact, ok := context[v] + if ok { + return compact, nil + } + return v, nil + } + return EncodeSHACLObject(value.GetObj(), path, state) +} + +func DecodeString(data any, path Path, context map[string]string) (string, error) { + v, ok := data.(string) + if ! ok { + return v, &DecodeError{path, "String expected. Got " + reflect.TypeOf(data).Name()} + } + return v, nil +} + +func EncodeString(value string, path Path, context map[string]string, state *EncodeState) (any, error) { + return value, nil +} + +func DecodeIRI(data any, path Path, context map[string]string) (string, error) { + s, err := DecodeString(data, path, context) + if err != nil { + return s, err + } + + for k, v := range context { + if s == v { + s = k + break + } + } + + if ! IsBlankNode(s) && ! IsIRI(s) { + return s, &DecodeError{path, "Must be blank node or IRI. Got '" + s + "'"} + } + + return s, nil +} + +func EncodeIRI(value string, path Path, context map[string]string, state *EncodeState) (any, error) { + compact, ok := context[value] + if ok { + return compact, nil + } + return value, nil +} + +func DecodeBoolean(data any, path Path, context map[string]string) (bool, error) { + v, ok := data.(bool) + if ! ok { + return v, &DecodeError{path, "Boolean expected. Got " + reflect.TypeOf(data).Name()} + } + return v, nil +} + +func EncodeBoolean(value bool, path Path, context map[string]string, state *EncodeState) (any, error) { + return value, nil +} + +func DecodeInteger(data any, path Path, context map[string]string) (int, error) { + switch data.(type) { + case int: + return data.(int), nil + case float64: + v := data.(float64) + if v == float64(int64(v)) { + return int(v), nil + } + return 0, &DecodeError{path, "Value must be an integer. Got " + fmt.Sprintf("%f", v)} + default: + return 0, &DecodeError{path, "Integer expected. Got " + reflect.TypeOf(data).Name()} + } +} + +func EncodeInteger(value int, path Path, context map[string]string, state *EncodeState) (any, error) { + return value, nil +} + +func DecodeFloat(data any, path Path, context map[string]string) (float64, error) { + switch data.(type) { + case float64: + return data.(float64), nil + case string: + v, err := strconv.ParseFloat(data.(string), 64) + if err != nil { + return 0, err + } + return v, nil + default: + return 0, &DecodeError{path, "Float expected. Got " + reflect.TypeOf(data).Name()} + } +} + +func EncodeFloat(value float64, path Path, context map[string]string, state *EncodeState) (any, error) { + return strconv.FormatFloat(value, 'f', -1, 64), nil +} + +const UtcFormatStr = "%Y-%m-%dT%H:%M:%SZ" +const TzFormatStr = "%Y-%m-%dT%H:%M:%S%:z" + +func decodeDateTimeString(data any, path Path, re *regexp.Regexp) (time.Time, error) { + v, ok := data.(string) + if ! ok { + return time.Time{}, &DecodeError{path, "String expected. Got " + reflect.TypeOf(data).Name()} + } + + match := re.FindStringSubmatch(v) + + if match == nil { + return time.Time{}, &DecodeError{path, "Invalid date time string '" + v + "'"} + } + + var format string + s := match[1] + tzstr := match[2] + + switch tzstr { + case "Z": + s += "+00:00" + format = "%Y-%m-%dT%H:%M:%S%:z" + case "": + format = "%Y-%m-%dT%H:%M:%S" + default: + s += tzstr + format = "%Y-%m-%dT%H:%M:%S%:z" + } + + t, err := strftime.Parse(format, v) + if err != nil { + return time.Time{}, &DecodeError{path, "Invalid date time string '" + v + "': " + err.Error()} + } + return t, nil +} + +var dateTimeRegex = regexp.MustCompile(`^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})(Z|[+-]\d{2}:\d{2})?$`) +func DecodeDateTime(data any, path Path, context map[string]string) (time.Time, error) { + return decodeDateTimeString(data, path, dateTimeRegex) +} + +var dateTimeStampRegex = regexp.MustCompile(`^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})(Z|[+-]\d{2}:\d{2})$`) +func DecodeDateTimeStamp(data any, path Path, context map[string]string) (time.Time, error) { + return decodeDateTimeString(data, path, dateTimeStampRegex) +} + +func EncodeDateTime(value time.Time, path Path, context map[string]string, state *EncodeState) (any, error) { + if value.Location() == time.UTC { + return strftime.Format(UtcFormatStr, value), nil + } + return strftime.Format(TzFormatStr, value), nil +} + +func DecodeList[T any](data any, path Path, context map[string]string, f func (any, Path, map[string]string) (T, error)) ([]T, error) { + lst, ok := data.([]interface{}) + if ! ok { + return nil, &DecodeError{path, "Must be a list"} + } + + var result []T + for idx, v := range lst { + sub_path := path.PushIndex(idx) + item, err := f(v, sub_path, context) + if err != nil { + return nil, err + } + result = append(result, item) + } + + return result, nil +} + +func EncodeList[T any](value []T, path Path, context map[string]string, state *EncodeState, f func (T, Path, map[string]string, *EncodeState) (any, error)) (any, error) { + lst := []any{} + for idx, v := range value { + val, err := f(v, path.PushIndex(idx), context, state) + if err != nil { + return lst, err + } + + lst = append(lst, val) + } + return lst, nil +} + +// IRI Validation +func IsIRI(iri string) bool { + if strings.HasPrefix(iri, "_:") { + return false + } + if strings.Contains(iri, ":") { + return true + } + return false +} + +func IsBlankNode(iri string) bool { + return strings.HasPrefix(iri, "_:") +} + +// Optional +type Optional[T any] struct { + value *T +} + +func (self Optional[T]) Get() T { + return *self.value +} + +func (self Optional[T]) GetDefault(val T) T { + if ! self.IsSet() { + return val + } + return *self.value +} + +func (self Optional[T]) IsSet() bool { + return self.value != nil +} + +func NewOptional[T any](value T) Optional[T] { + return Optional[T]{&value} +} + +func NewEmptyOptional[T any]() Optional[T] { + return Optional[T]{nil} +} + +// Validator +type Validator[T any] interface { + Check(T, string) error +} + +func ValueToString(val any) string { + switch val.(type) { + case string: + return val.(string) + case int: + return strconv.Itoa(val.(int)) + case time.Time: + t := val.(time.Time) + if t.Location() == time.UTC { + return strftime.Format(UtcFormatStr, t) + } + return strftime.Format(TzFormatStr, t) + } + panic("Unsupported Type " + reflect.TypeOf(val).Name()) +} + + +// ID Validator +type IDValidator struct {} + +func (self IDValidator) Check(val string, name string) error { + if ! IsIRI(val) && ! IsBlankNode(val) { + return &ValidationError{name, "Must be an IRI or a Blank Node"} + } + return nil +} + + +// Regex Validator +type RegexValidator[T int | time.Time | string] struct { + Regex string +} + +func (self RegexValidator[T]) Check(val T, name string) error { + s := ValueToString(val) + + m, err := regexp.MatchString(self.Regex, s) + if err != nil { + return err + } + if ! m { + return &ValidationError{name, "Value '" + s + "' does not match pattern"} + } + return nil +} + +// Integer Min Validator +type IntegerMinValidator struct { + Min int +} + +func (self IntegerMinValidator) Check(val int, name string) error { + if val < self.Min { + return &ValidationError{name, "Value " + strconv.Itoa(val) + " is less than minimum " + strconv.Itoa(self.Min)} + } + return nil +} + +// Integer Max Validator +type IntegerMaxValidator struct { + Max int +} + +func (self IntegerMaxValidator) Check(val int, name string) error { + if val > self.Max { + return &ValidationError{name, "Value " + strconv.Itoa(val) + " is greater than maximum" + strconv.Itoa(self.Max)} + } + return nil +} + +// Enum Validator +type EnumValidator struct { + Values []string +} + +func (self EnumValidator) Check(val string, name string) error { + for _, v := range self.Values { + if val == v { + return nil + } + } + return &ValidationError{name, "Value '" + val + "' is not a valid enumerated value" } +} + +// Property +type PropertyInterface[T any] interface { + Get() T + Set(val T) error + Delete() + IsSet() bool + Walk(path Path, visit Visit) +} + +type Property[T any] struct { + value Optional[T] + name string + validators []Validator[T] +} + +func NewProperty[T any](name string, validators []Validator[T]) Property[T] { + return Property[T]{ + value: NewEmptyOptional[T](), + name: name, + validators: validators, + } +} + +func (self *Property[T]) Get() T { + return self.value.Get() +} + +func (self *Property[T]) Set(val T) error { + for _, validator := range self.validators { + err := validator.Check(val, self.name) + if err != nil { + return err + } + } + + self.value = NewOptional(val) + return nil +} + +func (self *Property[T]) Delete() { + self.value = NewEmptyOptional[T]() +} + +func (self *Property[T]) IsSet() bool { + return self.value.IsSet() +} + +func (self *Property[T]) Check(path Path, handler ErrorHandler) bool { + if ! self.value.IsSet() { + return true + } + + var valid bool + valid = true + + for _, validator := range self.validators { + err := validator.Check(self.value.Get(), self.name) + if err != nil { + if handler != nil { + handler.HandleError(err, path) + } + valid = false + } + } + return valid +} + +func (self *Property[T]) Walk(path Path, visit Visit) { + if ! self.value.IsSet() { + return + } + + visit(path.PushPath(self.name), self.value.Get()) +} + +// Ref Property +type RefPropertyInterface[T SHACLObject] interface { + PropertyInterface[Ref[T]] + + SetObj(val T) error + SetIRI(iri string) error + + GetIRI() string + GetObj() T + IsObj() bool + IsIRI() bool +} + +type RefProperty[T SHACLObject] struct { + Property[Ref[T]] +} + +func NewRefProperty[T SHACLObject](name string, validators []Validator[Ref[T]]) RefProperty[T] { + return RefProperty[T]{ + Property: Property[Ref[T]]{ + value: NewEmptyOptional[Ref[T]](), + name: name, + validators: validators, + }, + } +} + +func (self *RefProperty[T]) SetObj(obj T) error { + // Shorthand to assign an object by making a reference to it + return self.Set(MakeObjectRef(obj)) +} + +func (self *RefProperty[T]) SetIRI(iri string) error { + // Shorthand to assign an IRI by making a reference to it + return self.Set(MakeIRIRef[T](iri)) +} + +func (self *RefProperty[T]) GetIRI() string { + // Shorthand to get the IRI value + return self.Get().GetIRI() +} + +func (self *RefProperty[T]) GetObj() T { + // Shorthand to get the Object value + return self.Get().GetObj() +} + +func (self *RefProperty[T]) IsSet() bool { + return self.Property.IsSet() && self.Get().IsSet() +} + +func (self *RefProperty[T]) IsObj() bool { + // Shorthand to check if the property references an object + return self.Property.IsSet() && self.Get().IsObj() +} + +func (self *RefProperty[T]) IsIRI() bool { + // Shorthand to check if the property references an IRI + return self.Property.IsSet() && self.Get().IsIRI() +} + +func (self *RefProperty[T]) Walk(path Path, visit Visit) { + if ! self.IsSet() { + return + } + + r, err := ConvertRef[SHACLObject](self.value.Get()) + if err != nil { + return + } + + visit(path.PushPath(self.name), r) +} + +// List Property +type ListPropertyInterface[T any] interface { + Get() []T + Set(val []T) error + Append(val T) error + Delete() + Walk(path Path, visit Visit) + IsSet() bool +} + +type ListProperty[T any] struct { + value []T + name string + validators []Validator[T] +} + +func NewListProperty[T any](name string, validators []Validator[T]) ListProperty[T] { + return ListProperty[T]{ + value: []T{}, + name: name, + validators: validators, + } +} + +func (self *ListProperty[T]) Get() []T { + return self.value +} + +func (self *ListProperty[T]) Set(val []T) error { + for _, v := range val { + for _, validator := range self.validators { + err := validator.Check(v, self.name) + if err != nil { + return err + } + } + } + + self.value = val + return nil +} + +func (self *ListProperty[T]) Append(val T) error { + for _, validator := range self.validators { + err := validator.Check(val, self.name) + if err != nil { + return err + } + } + + self.value = append(self.value, val) + return nil +} + +func (self *ListProperty[T]) Delete() { + self.value = []T{} +} + +func (self *ListProperty[T]) IsSet() bool { + return self.value != nil && len(self.value) > 0 +} + +func (self *ListProperty[T]) Check(path Path, handler ErrorHandler) bool { + var valid bool + valid = true + + for idx, v := range self.value { + for _, validator := range self.validators { + err := validator.Check(v, self.name) + if err != nil { + if handler != nil { + handler.HandleError(err, path.PushIndex(idx)) + } + valid = false + } + } + } + return valid +} + +func (self *ListProperty[T]) Walk(path Path, visit Visit) { + sub_path := path.PushPath(self.name) + + for idx, v := range self.value { + visit(sub_path.PushIndex(idx), v) + } +} + +type RefListProperty[T SHACLObject] struct { + ListProperty[Ref[T]] +} + +func NewRefListProperty[T SHACLObject](name string, validators []Validator[Ref[T]]) RefListProperty[T] { + return RefListProperty[T]{ + ListProperty: ListProperty[Ref[T]]{ + value: []Ref[T]{}, + name: name, + validators: validators, + }, + } +} + +func (self *RefListProperty[T]) Walk(path Path, visit Visit) { + sub_path := path.PushPath(self.name) + + for idx, v := range self.value { + r, err := ConvertRef[SHACLObject](v) + if err != nil { + visit(sub_path.PushIndex(idx), r) + } + } +} + +{% for class in classes %} +{%- for l in class.comment.splitlines() %} +{{ ("// " + l).rstrip() }} +{% endfor -%} +{% set is_public = not class.is_abstract or class.is_extensible -%} +type {{ struct_name(class) }} struct { +{%- if class.parent_ids %} +{%- for p in class.parent_ids %} + {{ struct_name(classes.get(p)) }} +{%- endfor %} +{%- else %} + SHACLObjectBase +{%- endif %} +{%- if class.is_extensible %} + SHACLExtensibleBase +{%- endif %} +{% for prop in class.properties %} + {%- for l in prop.comment.splitlines() %} + {{ ("// " + l).rstrip() }} + {%- endfor %} + {%- if not prop.enum_values and prop.class_id %} + {{ prop_name(prop) }} Ref{% if prop_is_list(prop) %}List{% endif %}Property[{{ interface_name(classes.get(prop.class_id)) }}] + {%- else %} + {{ prop_name(prop) }} {% if prop_is_list(prop) %}List{% endif %}Property[{{ prop_go_type(prop, classes) }}] + {%- endif %} +{%- endfor %} +} +{% for member in class.named_individuals %} +{%- for l in member.comment.splitlines() %} +{{ ("// " + l).rstrip() }} +{% endfor -%} +const {{ varname(*class.clsname) }}{{ varname(member.varname) }} = "{{ member._id }}" +{%- endfor %} + +type {{ struct_name(class) }}Type struct { + SHACLTypeBase +} +var {{ class_type_var(class) }} {{ struct_name(class) }}Type + +{%- for prop in class.properties %} +var {{ prop_ctx_name(class, prop) }} = map[string]string{ +{%- if prop.enum_values %} +{%- for value in prop.enum_values %} + "{{ value }}": "{{ context.compact_vocab(value, prop.path) }}", +{%- endfor %} +{%- elif prop.class_id %} +{%- for value in get_all_named_individuals(classes.get(prop.class_id)) %} + {%- if context.compact_vocab(value, prop.path) != value %} + "{{ value }}": "{{ context.compact_vocab(value, prop.path) }}", + {%- endif %} +{%- endfor -%} +{%- endif -%} +} +{%- endfor %} + +func Decode{{ interface_name(class) }} (data any, path Path, context map[string]string) (Ref[{{ interface_name(class) }}], error) { + return DecodeRef[{{ interface_name(class) }}](data, path, context, {{ class_type_var(class) }}) +} + +func (self {{ struct_name(class) }}Type) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.({{ interface_name(class) }}) + _ = obj + switch name { +{%- for prop in class.properties %} + case "{{ prop.path }}"{% if context.compact_vocab(prop.path) != prop.path %}, "{{ context.compact_vocab(prop.path) }}"{% endif %}: + val, err := {{ prop_decode_func(class, prop, classes) }} + if err != nil { + return false, err + } + err = obj.{{ varname(prop.varname) }}().Set(val) + if err != nil { + return false, err + } + return true, nil +{%- endfor %} + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self {{ struct_name(class) }}Type) Create() SHACLObject { + return Construct{{ struct_name(class) }}(&{{ struct_name(class) }}{}, self) +} + +func Construct{{ struct_name(class) }}(o *{{ struct_name(class) }}, typ SHACLType) *{{ struct_name(class) }} { +{%- if class.parent_ids %} +{%- for p in class.parent_ids %} + Construct{{ struct_name(classes.get(p)) }}(&o.{{ struct_name(classes.get(p)) }}, typ) +{%- endfor %} +{%- else %} + ConstructSHACLObjectBase(&o.SHACLObjectBase, typ) +{%- endif %} +{%- for prop in class.properties %} + { + validators := []Validator[{{ prop_go_type(prop, classes) }}]{} +{%- if prop.enum_values %} + validators = append(validators, + EnumValidator{[]string{ + {%- for e in prop.enum_values %} + "{{e}}", + {%- endfor %} + }}) +{%- elif prop.datatype == "http://www.w3.org/2001/XMLSchema#positiveInteger" %} + validators = append(validators, IntegerMinValidator{1}) +{%- elif prop.datatype == "http://www.w3.org/2001/XMLSchema#nonNegativeInteger" %} + validators = append(validators, IntegerMinValidator{0}) +{%- endif %} +{%- if prop.pattern %} + validators = append(validators, RegexValidator[{{ prop_go_type(prop, classes) }}]{`{{ prop.pattern }}`}) +{%- endif %} + {%- if not prop.enum_values and prop.class_id %} + o.{{ prop_name(prop) }} = NewRef{% if prop_is_list(prop) %}List{% endif %}Property[{{ interface_name(classes.get(prop.class_id)) }}]("{{ prop_name(prop) }}", validators) + {%- else %} + o.{{ prop_name(prop) }} = New{% if prop_is_list(prop) %}List{% endif %}Property[{{ prop_go_type(prop, classes) }}]("{{ prop_name(prop) }}", validators) + {%- endif %} + } +{%- endfor %} + return o +} + +type {{ interface_name(class) }} interface { +{%- if class.parent_ids %} +{%- for p in class.parent_ids %} + {{ interface_name(classes.get(p)) }} +{%- endfor %} +{%- else %} + SHACLObject +{%- endif %} +{%- for prop in class.properties %} +{%- if prop_is_list(prop) %} + {{ varname(prop.varname) }}() ListPropertyInterface[{{ prop_go_type(prop, classes) }}] +{%- elif not prop.enum_values and prop.class_id %} + {{ varname(prop.varname) }}() RefPropertyInterface[{{ interface_name(classes.get(prop.class_id)) }}] +{%- else %} + {{ varname(prop.varname) }}() PropertyInterface[{{ prop_go_type(prop, classes) }}] +{%- endif %} +{%- endfor %} +} + +{% if not class.is_abstract %} +func Make{{ varname(*class.clsname) }}() {{ interface_name(class) }} { + return Construct{{ struct_name(class) }}(&{{ struct_name(class) }}{}, {{ class_type_var(class) }}) +} + +func Make{{ varname(*class.clsname) }}Ref() Ref[{{ interface_name(class) }}] { + o := Make{{ varname(*class.clsname) }}() + return MakeObjectRef[{{ interface_name(class) }}](o) +} +{%- endif %} + +func (self *{{ struct_name(class) }}) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true +{%- if class.parent_ids %} +{%- for p in class.parent_ids %} + if ! self.{{ struct_name(classes.get(p)) }}.Validate(path, handler) { + valid = false + } +{%- endfor %} +{%- else %} + if ! self.SHACLObjectBase.Validate(path, handler) { + valid = false + } +{%- endif %} +{%- for prop in class.properties %} + { + prop_path := path.PushPath("{{ prop_name(prop) }}") + if ! self.{{ prop_name(prop) }}.Check(prop_path, handler) { + valid = false + } +{%- if prop_is_list(prop) %} + {%- if not prop.min_count is none %} + if len(self.{{ prop_name(prop) }}.Get()) < {{ prop.min_count }} { + if handler != nil { + handler.HandleError(&ValidationError{ + "{{ prop_name(prop) }}", + "Too few elements. Minimum of {{ prop.min_count }} required"}, + prop_path) + } + valid = false + } + {%- endif %} + {%- if not prop.max_count is none %} + if len(self.{{ prop_name(prop) }}.Get()) > {{ prop.max_count }} { + if handler != nil { + handler.HandleError(&ValidationError{ + "{{ prop_name(prop) }}", + "Too many elements. Maximum of {{ prop.max_count }} allowed"}, + prop_path) + } + valid = false + } + {%- endif %} +{%- else %} + {%- if not prop.min_count is none and prop.min_count > 0 %} + if ! self.{{ prop_name(prop) }}.IsSet() { + if handler != nil { + handler.HandleError(&ValidationError{"{{ prop_name(prop) }}", "Value is required"}, prop_path) + } + valid = false + } + {%- endif %} +{%- endif %} + } +{%- endfor %} + return valid +} + +func (self *{{ struct_name(class) }}) Walk(path Path, visit Visit) { +{%- if class.parent_ids %} +{%- for p in class.parent_ids %} + self.{{ struct_name(classes.get(p)) }}.Walk(path, visit) +{%- endfor %} +{%- else %} + self.SHACLObjectBase.Walk(path, visit) +{%- endif %} +{%- for prop in class.properties %} + self.{{ prop_name(prop) }}.Walk(path, visit) +{%- endfor %} +} + +{% for prop in class.properties %} +{%- if prop_is_list(prop) %} +func (self *{{ struct_name(class) }}) {{ varname(prop.varname) }}() ListPropertyInterface[{{ prop_go_type(prop, classes) }}] { return &self.{{ prop_name(prop) }} } +{%- elif not prop.enum_values and prop.class_id %} +func (self *{{ struct_name(class) }}) {{ varname(prop.varname) }}() RefPropertyInterface[{{ interface_name(classes.get(prop.class_id)) }}] { return &self.{{ prop_name(prop) }} } +{%- else %} +func (self *{{ struct_name(class) }}) {{ varname(prop.varname) }}() PropertyInterface[{{ prop_go_type(prop, classes) }}] { return &self.{{ prop_name(prop) }} } +{%- endif %} +{%- endfor %} + +func (self *{{ struct_name(class) }}) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { +{%- if class.parent_ids %} +{%- for p in class.parent_ids %} + if err := self.{{ struct_name(classes.get(p)) }}.EncodeProperties(data, path, state); err != nil { + return err + } +{%- endfor %} +{%- else %} + if err := self.SHACLObjectBase.EncodeProperties(data, path, state); err != nil { + return err + } +{%- endif %} +{%- for prop in class.properties %} + if self.{{ prop_name(prop) }}.IsSet() { + val, err := {{ prop_encode_func(class, prop, classes) }} + if err != nil { + return err + } + data["{{ context.compact_vocab(prop.path) }}"] = val + } +{%- endfor %} +{%- if class.is_extensible %} + self.SHACLExtensibleBase.EncodeExtProperties(data, path) +{%- endif %} + return nil +} +{% endfor %} + +func init() { + objectTypes = make(map[string] SHACLType) + +{%- for class in classes %} + {{ class_type_var(class) }} = {{ struct_name(class) }}Type{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "{{ class._id }}", + {%- if context.compact_iri(class._id) != class._id %} + compactTypeIRI: NewOptional[string]("{{ context.compact_iri(class._id) }}"), + {%- endif %} + isAbstract: {% if class.is_abstract %}true{% else %}false{% endif %}, + nodeKind: NewOptional[int](NodeKind{{ class.node_kind.split('#')[-1] }}), + {%- if class.is_extensible %} + isExtensible: NewOptional[bool](true), + {%- endif %} + {%- if class.id_property %} + idAlias: NewOptional[string]("{{ class.id_property }}"), + {%- endif %} + parentIRIs: []string{ {%- for p in class.parent_ids %} + "{{ p }}", + {%- endfor %} + }, + }, + } + RegisterType({{ class_type_var(class) }}) +{%- endfor %} +} diff --git a/testfixtures/jsonvalidation.py b/testfixtures/jsonvalidation.py index 7385bca..262c054 100644 --- a/testfixtures/jsonvalidation.py +++ b/testfixtures/jsonvalidation.py @@ -524,6 +524,18 @@ def node_kind_tests(name, blank, iri): }, }, ), + ( + "Nested extensible class with non-IRI type", + False, + { + "@context": CONTEXT, + "@type": "link-class", + "link-class-link-prop": { + "@type": "not-an-iri", + "extensible-class/required": "foo", + }, + }, + ), ( "Nested extensible class with custom type", True, diff --git a/tests/expect/golang/context/test-context.go b/tests/expect/golang/context/test-context.go new file mode 100644 index 0000000..1b889d5 --- /dev/null +++ b/tests/expect/golang/context/test-context.go @@ -0,0 +1,4929 @@ +// +// +// + +package model + +import ( + "encoding/json" + "fmt" + "reflect" + "regexp" + "sort" + "strconv" + "strings" + "time" + + "github.com/ncruces/go-strftime" +) + +// Validation Error +type ValidationError struct { + Property string + Err string +} + +func (e *ValidationError) Error() string { return e.Property + ": " + e.Err } + +// Conversion Error +type ConversionError struct { + From string + To string +} + +func (e *ConversionError) Error() string { + return "Unable to convert from " + e.From + " to " + e.To +} + +// Decode Error +type DecodeError struct { + Path Path + Err string +} + +func (e *DecodeError) Error() string { + return e.Path.ToString() + ": " + e.Err +} + +type EncodeError struct { + Path Path + Err string +} + +func (e *EncodeError) Error() string { + return e.Path.ToString() + ": " + e.Err +} + +// Path +type Path struct { + Path []string +} + +func (p *Path) PushPath(s string) Path { + new_p := *p + new_p.Path = append(new_p.Path, s) + return new_p +} + +func (p *Path) PushIndex(idx int) Path { + return p.PushPath("[" + strconv.Itoa(idx) + "]") +} + +func (p *Path) ToString() string { + return "." + strings.Join(p.Path, ".") +} + +// Error Handler +type ErrorHandler interface { + HandleError(error, Path) +} + +// Reference +type Ref[T SHACLObject] interface { + GetIRI() string + GetObj() T + IsSet() bool + IsObj() bool + IsIRI() bool +} + +type ref[T SHACLObject] struct { + obj *T + iri string +} + +func (r ref[T]) GetIRI() string { + if r.iri != "" { + return r.iri + } + if r.obj != nil { + o := *r.obj + if o.ID().IsSet() { + return o.ID().Get() + } + } + return "" +} + +func (r ref[T]) GetObj() T { + return *r.obj +} + +func (r ref[T]) IsSet() bool { return r.IsIRI() || r.IsObj() } +func (r ref[T]) IsObj() bool { return r.obj != nil } +func (r ref[T]) IsIRI() bool { return r.iri != "" } + +func MakeObjectRef[T SHACLObject](obj T) Ref[T] { + return ref[T]{&obj, ""} +} + +func MakeIRIRef[T SHACLObject](iri string) Ref[T] { + return ref[T]{nil, iri} +} + +// Convert one reference to another. Note that the output type is first so it +// can be specified, while the input type is generally inferred from the argument +func ConvertRef[TO SHACLObject, FROM SHACLObject](in Ref[FROM]) (Ref[TO], error) { + if in.IsObj() { + out_obj, ok := any(in.GetObj()).(TO) + if !ok { + return nil, &ConversionError{reflect.TypeOf(ref[FROM]{}).Name(), reflect.TypeOf(ref[TO]{}).Name()} + } + return ref[TO]{&out_obj, in.GetIRI()}, nil + } + return ref[TO]{nil, in.GetIRI()}, nil +} + +type Visit func(Path, any) + +// Base SHACL Object +type SHACLObjectBase struct { + // Object ID + id Property[string] + typ SHACLType + typeIRI string +} + +func (self *SHACLObjectBase) ID() PropertyInterface[string] { return &self.id } + +func (self *SHACLObjectBase) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + + switch self.typ.GetNodeKind() { + case NodeKindBlankNode: + if self.ID().IsSet() && ! IsBlankNode(self.ID().Get()) { + handler.HandleError(&ValidationError{ + "id", + "ID must by be blank node"}, + path.PushPath("id")) + valid = false + } + case NodeKindIRI: + if ! self.ID().IsSet() || ! IsIRI(self.ID().Get()) { + handler.HandleError(&ValidationError{ + "id", + "ID must be an IRI"}, + path.PushPath("id")) + valid = false + } + case NodeKindBlankNodeOrIRI: + if self.ID().IsSet() && ! IsBlankNode(self.ID().Get()) && ! IsIRI(self.ID().Get()) { + handler.HandleError(&ValidationError{ + "id", + "ID must be a blank node or IRI"}, + path.PushPath("id")) + valid = false + } + default: + panic("Unknown node kind") + } + + return valid +} + +func (self *SHACLObjectBase) Walk(path Path, visit Visit) { + self.id.Walk(path, visit) +} + +func (self *SHACLObjectBase) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if self.typeIRI != "" { + data["@type"] = self.typeIRI + } else { + data["@type"] = self.typ.GetCompactTypeIRI().GetDefault(self.typ.GetTypeIRI()) + } + + id_prop := self.typ.GetIDAlias().GetDefault("@id") + + if self.id.IsSet() { + val, err := EncodeIRI(self.id.Get(), path.PushPath(id_prop), map[string]string{}, state) + if err != nil { + return err + } + data[id_prop] = val + } + + return nil +} + +func (self *SHACLObjectBase) GetType() SHACLType { + return self.typ +} + +func (self *SHACLObjectBase) setTypeIRI(iri string) { + self.typeIRI = iri +} + +func ConstructSHACLObjectBase(o *SHACLObjectBase, typ SHACLType) *SHACLObjectBase { + o.id = NewProperty[string]("id", []Validator[string]{ IDValidator{}, }) + o.typ = typ + return o +} + +type SHACLObject interface { + ID() PropertyInterface[string] + Validate(path Path, handler ErrorHandler) bool + Walk(path Path, visit Visit) + EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error + GetType() SHACLType + setTypeIRI(iri string) +} + +func EncodeSHACLObject(o SHACLObject, path Path, state *EncodeState) (any, error) { + if state != nil { + if state.Written[o] { + if o.ID().IsSet() { + return o.ID().Get(), nil + } + + return nil, &EncodeError{ + path, + "Object referenced multiple times, but does not have an ID assigned", + } + } + + state.Written[o] = true + } + + d := make(map[string]interface{}) + return d, o.EncodeProperties(d, path, state) +} + +// Extensible Object + +type SHACLExtensibleBase struct { + properties map[string][]any +} + +func (self *SHACLExtensibleBase) GetExtProperty(name string) []any { + return self.properties[name] +} + +func (self *SHACLExtensibleBase) SetExtProperty(name string, value []any) { + if self.properties == nil { + self.properties = make(map[string][]any) + } + self.properties[name] = value +} + +func (self *SHACLExtensibleBase) DeleteExtProperty(name string) { + delete(self.properties, name) +} + +func (self *SHACLExtensibleBase) EncodeExtProperties(data map[string]any, path Path) error { + for k, values := range self.properties { + if len(values) == 0 { + continue + } + + lst := []any{} + for _, v := range values { + lst = append(lst, v) + } + data[k] = lst + } + return nil +} + +type SHACLExtensibleObject interface { + GetExtProperty(string) []any + SetExtProperty(string, []any) + DeleteExtProperty(string) +} + +// Type Metadata +const NodeKindBlankNode = 0 +const NodeKindIRI = 1 +const NodeKindBlankNodeOrIRI = 2 + +type SHACLType interface { + GetTypeIRI() string + GetCompactTypeIRI() Optional[string] + GetNodeKind() int + GetIDAlias() Optional[string] + DecodeProperty(SHACLObject, string, interface{}, Path) (bool, error) + Create() SHACLObject + IsAbstract() bool + IsExtensible() bool + IsSubClassOf(SHACLType) bool +} + +type SHACLTypeBase struct { + typeIRI string + compactTypeIRI Optional[string] + idAlias Optional[string] + isExtensible Optional[bool] + isAbstract bool + parentIRIs []string + nodeKind Optional[int] +} + +func (self SHACLTypeBase) GetTypeIRI() string { + return self.typeIRI +} + +func (self SHACLTypeBase) GetCompactTypeIRI() Optional[string] { + return self.compactTypeIRI +} + +func (self SHACLTypeBase) GetNodeKind() int { + if self.nodeKind.IsSet() { + return self.nodeKind.Get() + } + + for _, parent_id := range(self.parentIRIs) { + p := objectTypes[parent_id] + return p.GetNodeKind() + } + + return NodeKindBlankNodeOrIRI +} + +func (self SHACLTypeBase) GetIDAlias() Optional[string] { + if self.idAlias.IsSet() { + return self.idAlias + } + + for _, parent_id := range(self.parentIRIs) { + p := objectTypes[parent_id] + a := p.GetIDAlias() + if a.IsSet() { + return a + } + } + + return self.idAlias +} + +func (self SHACLTypeBase) IsAbstract() bool { + return self.isAbstract +} + +func (self SHACLTypeBase) IsExtensible() bool { + if self.isExtensible.IsSet() { + return self.isExtensible.Get() + } + + for _, parent_id := range(self.parentIRIs) { + p := objectTypes[parent_id] + if p.IsExtensible() { + return true + } + } + + return false +} + +func (self SHACLTypeBase) IsSubClassOf(other SHACLType) bool { + if other.GetTypeIRI() == self.typeIRI { + return true + } + + for _, parent_id := range(self.parentIRIs) { + p := objectTypes[parent_id] + if p.IsSubClassOf(other) { + return true + } + } + + return false +} + +type EncodeState struct { + Written map[SHACLObject]bool +} + +func (self SHACLTypeBase) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + id_alias := self.GetIDAlias() + if id_alias.IsSet() { + switch name { + case id_alias.Get(): + val, err := DecodeString(value, path.PushPath(name), map[string]string{}) + if err != nil { + return false, err + } + err = o.ID().Set(val) + if err != nil { + return false, err + } + return true, nil + case "@id": + return true, &DecodeError{ + path.PushPath(name), + "'@id' is not allowed for " + self.GetTypeIRI() + " which has an ID alias", + } + } + } else if name == "@id" { + val, err := DecodeString(value, path.PushPath(name), map[string]string{}) + if err != nil { + return false, err + } + err = o.ID().Set(val) + if err != nil { + return false, err + } + return true, nil + } + + for _, parent_id := range(self.parentIRIs) { + p := objectTypes[parent_id] + found, err := p.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + if self.isExtensible.GetDefault(false) { + obj := o.(SHACLExtensibleObject) + v, err := DecodeAny(value, path, map[string]string{}) + if err != nil { + return false, err + } + + lst, is_list := v.([]interface{}) + if is_list { + obj.SetExtProperty(name, lst) + } else { + obj.SetExtProperty(name, []interface{}{v}) + } + return true, nil + } + return false, nil +} + + +var objectTypes map[string] SHACLType + +func RegisterType(typ SHACLType) { + objectTypes[typ.GetTypeIRI()] = typ + compact := typ.GetCompactTypeIRI() + if compact.IsSet() { + objectTypes[compact.Get()] = typ + } +} + +// SHACLObjectSet +type SHACLObjectSet interface { + AddObject(r SHACLObject) + Decode(decoder *json.Decoder) error + Encode(encoder *json.Encoder) error + Walk(visit Visit) + Validate(handler ErrorHandler) bool +} + +type SHACLObjectSetObject struct { + objects []SHACLObject +} + +func (self *SHACLObjectSetObject) AddObject(r SHACLObject) { + self.objects = append(self.objects, r) +} + +func (self *SHACLObjectSetObject) Decode(decoder *json.Decoder) error { + path := Path{} + + var data map[string]interface{} + if err := decoder.Decode(&data); err != nil { + return err + } + + { + v, ok := data["@context"] + if ! ok { + return &DecodeError{path, "@context missing"} + } + + sub_path := path.PushPath("@context") + value, ok := v.(string) + if ! ok { + return &DecodeError{sub_path, "@context must be a string, or list of string"} + } + if value != "https://spdx.github.io/spdx-3-model/context.json" { + return &DecodeError{sub_path, "Wrong context URL '" + value + "'"} + } + } + + delete(data, "@context") + + decodeProxy := func (data any, path Path, context map[string]string) (SHACLObject, error) { + return DecodeSHACLObject[SHACLObject](data, path, context, nil) + } + + _, has_graph := data["@graph"] + if has_graph { + for k, v := range data { + switch k { + case "@graph": { + objs, err := DecodeList[SHACLObject]( + v, + path.PushPath("@graph"), + map[string]string{}, + decodeProxy, + ) + + if err != nil { + return err + } + + for _, obj := range objs { + self.AddObject(obj) + } + } + + default: + return &DecodeError{path, "Unknown property '" + k + "'"} + } + } + } else { + obj, err := decodeProxy(data, path, map[string]string{}) + if err != nil { + return err + } + + self.AddObject(obj) + } + + return nil +} + +func (self *SHACLObjectSetObject) Encode(encoder *json.Encoder) error { + data := make(map[string]interface{}) + data["@context"] = "https://spdx.github.io/spdx-3-model/context.json" + path := Path{} + state := EncodeState{ + Written: make(map[SHACLObject]bool), + } + + ref_counts := make(map[SHACLObject]int) + + visit := func (path Path, v any) { + r, ok := v.(Ref[SHACLObject]) + if ! ok { + return + } + + if ! r.IsObj() { + return + } + + o := r.GetObj() + + // Remove blank nodes for reassignment + if o.ID().IsSet() && IsBlankNode(o.ID().Get()) { + o.ID().Delete() + } + + ref_counts[o] = ref_counts[o] + 1 + } + + self.Walk(visit) + + blank_count := 0 + for o, count := range ref_counts { + if count <= 1 { + continue + } + + if o.ID().IsSet() { + continue + } + + o.ID().Set(fmt.Sprintf("_:%d", blank_count)) + blank_count += 1 + } + + if len(self.objects) == 1 { + err := self.objects[0].EncodeProperties(data, path, &state) + if err != nil { + return err + } + } else if len(self.objects) > 1 { + // All objects directly added to the object set should be written as + // top level objects, so mark then as written until they are ready to + // be serialized, which will force them to be referenced by IRI until + // we are ready + for _, o := range self.objects { + state.Written[o] = true + } + + graph_path := path.PushPath("@graph") + lst := []interface{}{} + for idx, o := range self.objects { + // Remove this object from the written set now so it gets serialized + delete(state.Written, o) + + d, err := EncodeSHACLObject(o, graph_path.PushIndex(idx), &state) + if err != nil { + return err + } + lst = append(lst, d) + } + + data["@graph"] = lst + } + + return encoder.Encode(data) +} + +func (self *SHACLObjectSetObject) Walk(visit Visit) { + path := Path{} + visited := map[SHACLObject]bool{} + + visit_proxy := func (path Path, v any) { + switch v.(type) { + case Ref[SHACLObject]: + r := v.(Ref[SHACLObject]) + if ! r.IsObj() { + visit(path, v) + return + } + + o := r.GetObj() + _, ok := visited[o] + if ok { + return + } + visited[o] = true + visit(path, v) + o.Walk(path, visit) + return + + default: + visit(path, v) + return + } + } + + for idx, o := range(self.objects) { + sub_path := path.PushIndex(idx) + visit_proxy(sub_path, MakeObjectRef(o)) + } +} + +func (self *SHACLObjectSetObject) Validate(handler ErrorHandler) bool { + valid := true + + visit_proxy := func (path Path, v any) { + r, ok := v.(Ref[SHACLObject]) + if ! ok { + return + } + + if ! r.IsObj() { + return + } + + if ! r.GetObj().Validate(path, handler) { + valid = false + } + } + + self.Walk(visit_proxy) + + return valid +} + +func NewSHACLObjectSet() SHACLObjectSet { + os := SHACLObjectSetObject{} + return &os +} + +func DecodeAny(data any, path Path, context map[string]string) (any, error) { + switch data.(type) { + case map[string]interface{}: + return DecodeRef[SHACLObject](data, path, context, nil) + case string: + return DecodeString(data, path, context) + case int: + return DecodeInteger(data, path, context) + case float64: + return DecodeFloat(data, path, context) + case bool: + return DecodeBoolean(data, path, context) + case []interface{}: + return DecodeList[any](data, path, context, DecodeAny) + default: + return nil, &DecodeError{path, "Unknown type "+ reflect.TypeOf(data).Name()} + } +} + +func DecodeSHACLObject[T SHACLObject](data any, path Path, context map[string]string, targetType SHACLType) (T, error) { + dict, ok := data.(map[string]interface{}) + if ! ok { + return *new(T), &DecodeError{path, "Expected dictionary or string. Got " + reflect.TypeOf(data).Name()} + } + + var v interface{} + v, ok = dict["@type"] + if ! ok { + v, ok = dict["@type"] + if ! ok { + return *new(T), &DecodeError{path, "type missing"} + } + } + + var type_iri string + var create_type SHACLType + + type_iri, ok = v.(string) + if ! ok { + return *new(T), &DecodeError{path, "Wrong type for @type. Got " + reflect.TypeOf(v).Name()} + } + + iri_typ, ok := objectTypes[type_iri] + if ok { + if targetType != nil && !iri_typ.IsSubClassOf(targetType) { + return *new(T), &DecodeError{path, "Type " + type_iri + " is not valid where " + + targetType.GetTypeIRI() + " is expected"} + } + + if iri_typ.IsAbstract() { + return *new(T), &DecodeError{path, "Unable to create abstract type '" + type_iri + "'"} + } + + create_type = iri_typ + } else if targetType != nil && targetType.IsExtensible() { + // An extensible type is expected, so make one of the correct type + // + // Note: An abstract extensible class is actually allowed to be created + // here + create_type = targetType + } else { + if IsIRI(type_iri) { + // It's not clear exactly which type should be created. Search through + // all types and collect a list of possible Extensible types that are + // valid in this location. + possible := []SHACLType{} + for _, v := range objectTypes { + if ! v.IsExtensible() { + continue + } + + if v.IsAbstract() { + continue + } + + // If a type was specified, only subclasses of that type are + // allowed + if targetType != nil && ! v.IsSubClassOf(targetType) { + continue + } + + possible = append(possible, v) + } + + // Sort for determinism + sort.Slice(possible, func(i, j int) bool { + return possible[i].GetTypeIRI() < possible[j].GetTypeIRI() + }) + + for _, t := range(possible) { + // Ignore errors + o, err := DecodeSHACLObject[T](data, path, context, t) + if err == nil { + o.setTypeIRI(type_iri) + return o, nil + } + } + } + return *new(T), &DecodeError{path, "Unable to create object of type '" + type_iri + "' (no matching extensible object)"} + } + + obj, ok := create_type.Create().(T) + if ! ok { + return *new(T), &DecodeError{path, "Unable to create object of type '" + type_iri + "'"} + } + obj.setTypeIRI(type_iri) + + for k, v := range dict { + if k == "@type" { + continue + } + if k == "@type" { + continue + } + + sub_path := path.PushPath(k) + found, err := create_type.DecodeProperty(obj, k, v, sub_path) + if err != nil { + return *new(T), err + } + if ! found { + return *new(T), &DecodeError{path, "Unknown property '" + k + "'"} + } + } + + return obj, nil +} + +func DecodeRef[T SHACLObject](data any, path Path, context map[string]string, typ SHACLType) (Ref[T], error) { + switch data.(type) { + case string: + s, err := DecodeIRI(data, path, context) + if err != nil { + return nil, err + } + return MakeIRIRef[T](s), nil + } + + obj, err := DecodeSHACLObject[T](data, path, context, typ) + if err != nil { + return nil, err + } + + return MakeObjectRef[T](obj), nil +} + +func EncodeRef[T SHACLObject](value Ref[T], path Path, context map[string]string, state *EncodeState) (any, error) { + if value.IsIRI() { + v := value.GetIRI() + compact, ok := context[v] + if ok { + return compact, nil + } + return v, nil + } + return EncodeSHACLObject(value.GetObj(), path, state) +} + +func DecodeString(data any, path Path, context map[string]string) (string, error) { + v, ok := data.(string) + if ! ok { + return v, &DecodeError{path, "String expected. Got " + reflect.TypeOf(data).Name()} + } + return v, nil +} + +func EncodeString(value string, path Path, context map[string]string, state *EncodeState) (any, error) { + return value, nil +} + +func DecodeIRI(data any, path Path, context map[string]string) (string, error) { + s, err := DecodeString(data, path, context) + if err != nil { + return s, err + } + + for k, v := range context { + if s == v { + s = k + break + } + } + + if ! IsBlankNode(s) && ! IsIRI(s) { + return s, &DecodeError{path, "Must be blank node or IRI. Got '" + s + "'"} + } + + return s, nil +} + +func EncodeIRI(value string, path Path, context map[string]string, state *EncodeState) (any, error) { + compact, ok := context[value] + if ok { + return compact, nil + } + return value, nil +} + +func DecodeBoolean(data any, path Path, context map[string]string) (bool, error) { + v, ok := data.(bool) + if ! ok { + return v, &DecodeError{path, "Boolean expected. Got " + reflect.TypeOf(data).Name()} + } + return v, nil +} + +func EncodeBoolean(value bool, path Path, context map[string]string, state *EncodeState) (any, error) { + return value, nil +} + +func DecodeInteger(data any, path Path, context map[string]string) (int, error) { + switch data.(type) { + case int: + return data.(int), nil + case float64: + v := data.(float64) + if v == float64(int64(v)) { + return int(v), nil + } + return 0, &DecodeError{path, "Value must be an integer. Got " + fmt.Sprintf("%f", v)} + default: + return 0, &DecodeError{path, "Integer expected. Got " + reflect.TypeOf(data).Name()} + } +} + +func EncodeInteger(value int, path Path, context map[string]string, state *EncodeState) (any, error) { + return value, nil +} + +func DecodeFloat(data any, path Path, context map[string]string) (float64, error) { + switch data.(type) { + case float64: + return data.(float64), nil + case string: + v, err := strconv.ParseFloat(data.(string), 64) + if err != nil { + return 0, err + } + return v, nil + default: + return 0, &DecodeError{path, "Float expected. Got " + reflect.TypeOf(data).Name()} + } +} + +func EncodeFloat(value float64, path Path, context map[string]string, state *EncodeState) (any, error) { + return strconv.FormatFloat(value, 'f', -1, 64), nil +} + +const UtcFormatStr = "%Y-%m-%dT%H:%M:%SZ" +const TzFormatStr = "%Y-%m-%dT%H:%M:%S%:z" + +func decodeDateTimeString(data any, path Path, re *regexp.Regexp) (time.Time, error) { + v, ok := data.(string) + if ! ok { + return time.Time{}, &DecodeError{path, "String expected. Got " + reflect.TypeOf(data).Name()} + } + + match := re.FindStringSubmatch(v) + + if match == nil { + return time.Time{}, &DecodeError{path, "Invalid date time string '" + v + "'"} + } + + var format string + s := match[1] + tzstr := match[2] + + switch tzstr { + case "Z": + s += "+00:00" + format = "%Y-%m-%dT%H:%M:%S%:z" + case "": + format = "%Y-%m-%dT%H:%M:%S" + default: + s += tzstr + format = "%Y-%m-%dT%H:%M:%S%:z" + } + + t, err := strftime.Parse(format, v) + if err != nil { + return time.Time{}, &DecodeError{path, "Invalid date time string '" + v + "': " + err.Error()} + } + return t, nil +} + +var dateTimeRegex = regexp.MustCompile(`^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})(Z|[+-]\d{2}:\d{2})?$`) +func DecodeDateTime(data any, path Path, context map[string]string) (time.Time, error) { + return decodeDateTimeString(data, path, dateTimeRegex) +} + +var dateTimeStampRegex = regexp.MustCompile(`^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})(Z|[+-]\d{2}:\d{2})$`) +func DecodeDateTimeStamp(data any, path Path, context map[string]string) (time.Time, error) { + return decodeDateTimeString(data, path, dateTimeStampRegex) +} + +func EncodeDateTime(value time.Time, path Path, context map[string]string, state *EncodeState) (any, error) { + if value.Location() == time.UTC { + return strftime.Format(UtcFormatStr, value), nil + } + return strftime.Format(TzFormatStr, value), nil +} + +func DecodeList[T any](data any, path Path, context map[string]string, f func (any, Path, map[string]string) (T, error)) ([]T, error) { + lst, ok := data.([]interface{}) + if ! ok { + return nil, &DecodeError{path, "Must be a list"} + } + + var result []T + for idx, v := range lst { + sub_path := path.PushIndex(idx) + item, err := f(v, sub_path, context) + if err != nil { + return nil, err + } + result = append(result, item) + } + + return result, nil +} + +func EncodeList[T any](value []T, path Path, context map[string]string, state *EncodeState, f func (T, Path, map[string]string, *EncodeState) (any, error)) (any, error) { + lst := []any{} + for idx, v := range value { + val, err := f(v, path.PushIndex(idx), context, state) + if err != nil { + return lst, err + } + + lst = append(lst, val) + } + return lst, nil +} + +// IRI Validation +func IsIRI(iri string) bool { + if strings.HasPrefix(iri, "_:") { + return false + } + if strings.Contains(iri, ":") { + return true + } + return false +} + +func IsBlankNode(iri string) bool { + return strings.HasPrefix(iri, "_:") +} + +// Optional +type Optional[T any] struct { + value *T +} + +func (self Optional[T]) Get() T { + return *self.value +} + +func (self Optional[T]) GetDefault(val T) T { + if ! self.IsSet() { + return val + } + return *self.value +} + +func (self Optional[T]) IsSet() bool { + return self.value != nil +} + +func NewOptional[T any](value T) Optional[T] { + return Optional[T]{&value} +} + +func NewEmptyOptional[T any]() Optional[T] { + return Optional[T]{nil} +} + +// Validator +type Validator[T any] interface { + Check(T, string) error +} + +func ValueToString(val any) string { + switch val.(type) { + case string: + return val.(string) + case int: + return strconv.Itoa(val.(int)) + case time.Time: + t := val.(time.Time) + if t.Location() == time.UTC { + return strftime.Format(UtcFormatStr, t) + } + return strftime.Format(TzFormatStr, t) + } + panic("Unsupported Type " + reflect.TypeOf(val).Name()) +} + + +// ID Validator +type IDValidator struct {} + +func (self IDValidator) Check(val string, name string) error { + if ! IsIRI(val) && ! IsBlankNode(val) { + return &ValidationError{name, "Must be an IRI or a Blank Node"} + } + return nil +} + + +// Regex Validator +type RegexValidator[T int | time.Time | string] struct { + Regex string +} + +func (self RegexValidator[T]) Check(val T, name string) error { + s := ValueToString(val) + + m, err := regexp.MatchString(self.Regex, s) + if err != nil { + return err + } + if ! m { + return &ValidationError{name, "Value '" + s + "' does not match pattern"} + } + return nil +} + +// Integer Min Validator +type IntegerMinValidator struct { + Min int +} + +func (self IntegerMinValidator) Check(val int, name string) error { + if val < self.Min { + return &ValidationError{name, "Value " + strconv.Itoa(val) + " is less than minimum " + strconv.Itoa(self.Min)} + } + return nil +} + +// Integer Max Validator +type IntegerMaxValidator struct { + Max int +} + +func (self IntegerMaxValidator) Check(val int, name string) error { + if val > self.Max { + return &ValidationError{name, "Value " + strconv.Itoa(val) + " is greater than maximum" + strconv.Itoa(self.Max)} + } + return nil +} + +// Enum Validator +type EnumValidator struct { + Values []string +} + +func (self EnumValidator) Check(val string, name string) error { + for _, v := range self.Values { + if val == v { + return nil + } + } + return &ValidationError{name, "Value '" + val + "' is not a valid enumerated value" } +} + +// Property +type PropertyInterface[T any] interface { + Get() T + Set(val T) error + Delete() + IsSet() bool + Walk(path Path, visit Visit) +} + +type Property[T any] struct { + value Optional[T] + name string + validators []Validator[T] +} + +func NewProperty[T any](name string, validators []Validator[T]) Property[T] { + return Property[T]{ + value: NewEmptyOptional[T](), + name: name, + validators: validators, + } +} + +func (self *Property[T]) Get() T { + return self.value.Get() +} + +func (self *Property[T]) Set(val T) error { + for _, validator := range self.validators { + err := validator.Check(val, self.name) + if err != nil { + return err + } + } + + self.value = NewOptional(val) + return nil +} + +func (self *Property[T]) Delete() { + self.value = NewEmptyOptional[T]() +} + +func (self *Property[T]) IsSet() bool { + return self.value.IsSet() +} + +func (self *Property[T]) Check(path Path, handler ErrorHandler) bool { + if ! self.value.IsSet() { + return true + } + + var valid bool + valid = true + + for _, validator := range self.validators { + err := validator.Check(self.value.Get(), self.name) + if err != nil { + if handler != nil { + handler.HandleError(err, path) + } + valid = false + } + } + return valid +} + +func (self *Property[T]) Walk(path Path, visit Visit) { + if ! self.value.IsSet() { + return + } + + visit(path.PushPath(self.name), self.value.Get()) +} + +// Ref Property +type RefPropertyInterface[T SHACLObject] interface { + PropertyInterface[Ref[T]] + + SetObj(val T) error + SetIRI(iri string) error + + GetIRI() string + GetObj() T + IsObj() bool + IsIRI() bool +} + +type RefProperty[T SHACLObject] struct { + Property[Ref[T]] +} + +func NewRefProperty[T SHACLObject](name string, validators []Validator[Ref[T]]) RefProperty[T] { + return RefProperty[T]{ + Property: Property[Ref[T]]{ + value: NewEmptyOptional[Ref[T]](), + name: name, + validators: validators, + }, + } +} + +func (self *RefProperty[T]) SetObj(obj T) error { + // Shorthand to assign an object by making a reference to it + return self.Set(MakeObjectRef(obj)) +} + +func (self *RefProperty[T]) SetIRI(iri string) error { + // Shorthand to assign an IRI by making a reference to it + return self.Set(MakeIRIRef[T](iri)) +} + +func (self *RefProperty[T]) GetIRI() string { + // Shorthand to get the IRI value + return self.Get().GetIRI() +} + +func (self *RefProperty[T]) GetObj() T { + // Shorthand to get the Object value + return self.Get().GetObj() +} + +func (self *RefProperty[T]) IsSet() bool { + return self.Property.IsSet() && self.Get().IsSet() +} + +func (self *RefProperty[T]) IsObj() bool { + // Shorthand to check if the property references an object + return self.Property.IsSet() && self.Get().IsObj() +} + +func (self *RefProperty[T]) IsIRI() bool { + // Shorthand to check if the property references an IRI + return self.Property.IsSet() && self.Get().IsIRI() +} + +func (self *RefProperty[T]) Walk(path Path, visit Visit) { + if ! self.IsSet() { + return + } + + r, err := ConvertRef[SHACLObject](self.value.Get()) + if err != nil { + return + } + + visit(path.PushPath(self.name), r) +} + +// List Property +type ListPropertyInterface[T any] interface { + Get() []T + Set(val []T) error + Append(val T) error + Delete() + Walk(path Path, visit Visit) + IsSet() bool +} + +type ListProperty[T any] struct { + value []T + name string + validators []Validator[T] +} + +func NewListProperty[T any](name string, validators []Validator[T]) ListProperty[T] { + return ListProperty[T]{ + value: []T{}, + name: name, + validators: validators, + } +} + +func (self *ListProperty[T]) Get() []T { + return self.value +} + +func (self *ListProperty[T]) Set(val []T) error { + for _, v := range val { + for _, validator := range self.validators { + err := validator.Check(v, self.name) + if err != nil { + return err + } + } + } + + self.value = val + return nil +} + +func (self *ListProperty[T]) Append(val T) error { + for _, validator := range self.validators { + err := validator.Check(val, self.name) + if err != nil { + return err + } + } + + self.value = append(self.value, val) + return nil +} + +func (self *ListProperty[T]) Delete() { + self.value = []T{} +} + +func (self *ListProperty[T]) IsSet() bool { + return self.value != nil && len(self.value) > 0 +} + +func (self *ListProperty[T]) Check(path Path, handler ErrorHandler) bool { + var valid bool + valid = true + + for idx, v := range self.value { + for _, validator := range self.validators { + err := validator.Check(v, self.name) + if err != nil { + if handler != nil { + handler.HandleError(err, path.PushIndex(idx)) + } + valid = false + } + } + } + return valid +} + +func (self *ListProperty[T]) Walk(path Path, visit Visit) { + sub_path := path.PushPath(self.name) + + for idx, v := range self.value { + visit(sub_path.PushIndex(idx), v) + } +} + +type RefListProperty[T SHACLObject] struct { + ListProperty[Ref[T]] +} + +func NewRefListProperty[T SHACLObject](name string, validators []Validator[Ref[T]]) RefListProperty[T] { + return RefListProperty[T]{ + ListProperty: ListProperty[Ref[T]]{ + value: []Ref[T]{}, + name: name, + validators: validators, + }, + } +} + +func (self *RefListProperty[T]) Walk(path Path, visit Visit) { + sub_path := path.PushPath(self.name) + + for idx, v := range self.value { + r, err := ConvertRef[SHACLObject](v) + if err != nil { + visit(sub_path.PushIndex(idx), r) + } + } +} + + +// An Abstract class +type AbstractClassObject struct { + SHACLObjectBase + +} + + +type AbstractClassObjectType struct { + SHACLTypeBase +} +var abstractClassType AbstractClassObjectType + +func DecodeAbstractClass (data any, path Path, context map[string]string) (Ref[AbstractClass], error) { + return DecodeRef[AbstractClass](data, path, context, abstractClassType) +} + +func (self AbstractClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(AbstractClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self AbstractClassObjectType) Create() SHACLObject { + return ConstructAbstractClassObject(&AbstractClassObject{}, self) +} + +func ConstructAbstractClassObject(o *AbstractClassObject, typ SHACLType) *AbstractClassObject { + ConstructSHACLObjectBase(&o.SHACLObjectBase, typ) + return o +} + +type AbstractClass interface { + SHACLObject +} + + + +func (self *AbstractClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.SHACLObjectBase.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *AbstractClassObject) Walk(path Path, visit Visit) { + self.SHACLObjectBase.Walk(path, visit) +} + + + +func (self *AbstractClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.SHACLObjectBase.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} +type AbstractShClassObject struct { + SHACLObjectBase + +} + + +type AbstractShClassObjectType struct { + SHACLTypeBase +} +var abstractShClassType AbstractShClassObjectType + +func DecodeAbstractShClass (data any, path Path, context map[string]string) (Ref[AbstractShClass], error) { + return DecodeRef[AbstractShClass](data, path, context, abstractShClassType) +} + +func (self AbstractShClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(AbstractShClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self AbstractShClassObjectType) Create() SHACLObject { + return ConstructAbstractShClassObject(&AbstractShClassObject{}, self) +} + +func ConstructAbstractShClassObject(o *AbstractShClassObject, typ SHACLType) *AbstractShClassObject { + ConstructSHACLObjectBase(&o.SHACLObjectBase, typ) + return o +} + +type AbstractShClass interface { + SHACLObject +} + + + +func (self *AbstractShClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.SHACLObjectBase.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *AbstractShClassObject) Walk(path Path, visit Visit) { + self.SHACLObjectBase.Walk(path, visit) +} + + + +func (self *AbstractShClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.SHACLObjectBase.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// An Abstract class using the SPDX type +type AbstractSpdxClassObject struct { + SHACLObjectBase + +} + + +type AbstractSpdxClassObjectType struct { + SHACLTypeBase +} +var abstractSpdxClassType AbstractSpdxClassObjectType + +func DecodeAbstractSpdxClass (data any, path Path, context map[string]string) (Ref[AbstractSpdxClass], error) { + return DecodeRef[AbstractSpdxClass](data, path, context, abstractSpdxClassType) +} + +func (self AbstractSpdxClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(AbstractSpdxClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self AbstractSpdxClassObjectType) Create() SHACLObject { + return ConstructAbstractSpdxClassObject(&AbstractSpdxClassObject{}, self) +} + +func ConstructAbstractSpdxClassObject(o *AbstractSpdxClassObject, typ SHACLType) *AbstractSpdxClassObject { + ConstructSHACLObjectBase(&o.SHACLObjectBase, typ) + return o +} + +type AbstractSpdxClass interface { + SHACLObject +} + + + +func (self *AbstractSpdxClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.SHACLObjectBase.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *AbstractSpdxClassObject) Walk(path Path, visit Visit) { + self.SHACLObjectBase.Walk(path, visit) +} + + + +func (self *AbstractSpdxClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.SHACLObjectBase.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// A concrete class +type ConcreteClassObject struct { + AbstractClassObject + +} + + +type ConcreteClassObjectType struct { + SHACLTypeBase +} +var concreteClassType ConcreteClassObjectType + +func DecodeConcreteClass (data any, path Path, context map[string]string) (Ref[ConcreteClass], error) { + return DecodeRef[ConcreteClass](data, path, context, concreteClassType) +} + +func (self ConcreteClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(ConcreteClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self ConcreteClassObjectType) Create() SHACLObject { + return ConstructConcreteClassObject(&ConcreteClassObject{}, self) +} + +func ConstructConcreteClassObject(o *ConcreteClassObject, typ SHACLType) *ConcreteClassObject { + ConstructAbstractClassObject(&o.AbstractClassObject, typ) + return o +} + +type ConcreteClass interface { + AbstractClass +} + + +func MakeConcreteClass() ConcreteClass { + return ConstructConcreteClassObject(&ConcreteClassObject{}, concreteClassType) +} + +func MakeConcreteClassRef() Ref[ConcreteClass] { + o := MakeConcreteClass() + return MakeObjectRef[ConcreteClass](o) +} + +func (self *ConcreteClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.AbstractClassObject.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *ConcreteClassObject) Walk(path Path, visit Visit) { + self.AbstractClassObject.Walk(path, visit) +} + + + +func (self *ConcreteClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.AbstractClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// A concrete class +type ConcreteShClassObject struct { + AbstractShClassObject + +} + + +type ConcreteShClassObjectType struct { + SHACLTypeBase +} +var concreteShClassType ConcreteShClassObjectType + +func DecodeConcreteShClass (data any, path Path, context map[string]string) (Ref[ConcreteShClass], error) { + return DecodeRef[ConcreteShClass](data, path, context, concreteShClassType) +} + +func (self ConcreteShClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(ConcreteShClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self ConcreteShClassObjectType) Create() SHACLObject { + return ConstructConcreteShClassObject(&ConcreteShClassObject{}, self) +} + +func ConstructConcreteShClassObject(o *ConcreteShClassObject, typ SHACLType) *ConcreteShClassObject { + ConstructAbstractShClassObject(&o.AbstractShClassObject, typ) + return o +} + +type ConcreteShClass interface { + AbstractShClass +} + + +func MakeConcreteShClass() ConcreteShClass { + return ConstructConcreteShClassObject(&ConcreteShClassObject{}, concreteShClassType) +} + +func MakeConcreteShClassRef() Ref[ConcreteShClass] { + o := MakeConcreteShClass() + return MakeObjectRef[ConcreteShClass](o) +} + +func (self *ConcreteShClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.AbstractShClassObject.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *ConcreteShClassObject) Walk(path Path, visit Visit) { + self.AbstractShClassObject.Walk(path, visit) +} + + + +func (self *ConcreteShClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.AbstractShClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// A concrete class +type ConcreteSpdxClassObject struct { + AbstractSpdxClassObject + +} + + +type ConcreteSpdxClassObjectType struct { + SHACLTypeBase +} +var concreteSpdxClassType ConcreteSpdxClassObjectType + +func DecodeConcreteSpdxClass (data any, path Path, context map[string]string) (Ref[ConcreteSpdxClass], error) { + return DecodeRef[ConcreteSpdxClass](data, path, context, concreteSpdxClassType) +} + +func (self ConcreteSpdxClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(ConcreteSpdxClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self ConcreteSpdxClassObjectType) Create() SHACLObject { + return ConstructConcreteSpdxClassObject(&ConcreteSpdxClassObject{}, self) +} + +func ConstructConcreteSpdxClassObject(o *ConcreteSpdxClassObject, typ SHACLType) *ConcreteSpdxClassObject { + ConstructAbstractSpdxClassObject(&o.AbstractSpdxClassObject, typ) + return o +} + +type ConcreteSpdxClass interface { + AbstractSpdxClass +} + + +func MakeConcreteSpdxClass() ConcreteSpdxClass { + return ConstructConcreteSpdxClassObject(&ConcreteSpdxClassObject{}, concreteSpdxClassType) +} + +func MakeConcreteSpdxClassRef() Ref[ConcreteSpdxClass] { + o := MakeConcreteSpdxClass() + return MakeObjectRef[ConcreteSpdxClass](o) +} + +func (self *ConcreteSpdxClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.AbstractSpdxClassObject.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *ConcreteSpdxClassObject) Walk(path Path, visit Visit) { + self.AbstractSpdxClassObject.Walk(path, visit) +} + + + +func (self *ConcreteSpdxClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.AbstractSpdxClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// An enumerated type +type EnumTypeObject struct { + SHACLObjectBase + +} + +// The foo value of enumType +const EnumTypeFoo = "http://example.org/enumType/foo" +// The bar value of enumType +const EnumTypeBar = "http://example.org/enumType/bar" +// This value has no label +const EnumTypeNolabel = "http://example.org/enumType/nolabel" + +type EnumTypeObjectType struct { + SHACLTypeBase +} +var enumTypeType EnumTypeObjectType + +func DecodeEnumType (data any, path Path, context map[string]string) (Ref[EnumType], error) { + return DecodeRef[EnumType](data, path, context, enumTypeType) +} + +func (self EnumTypeObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(EnumType) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self EnumTypeObjectType) Create() SHACLObject { + return ConstructEnumTypeObject(&EnumTypeObject{}, self) +} + +func ConstructEnumTypeObject(o *EnumTypeObject, typ SHACLType) *EnumTypeObject { + ConstructSHACLObjectBase(&o.SHACLObjectBase, typ) + return o +} + +type EnumType interface { + SHACLObject +} + + +func MakeEnumType() EnumType { + return ConstructEnumTypeObject(&EnumTypeObject{}, enumTypeType) +} + +func MakeEnumTypeRef() Ref[EnumType] { + o := MakeEnumType() + return MakeObjectRef[EnumType](o) +} + +func (self *EnumTypeObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.SHACLObjectBase.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *EnumTypeObject) Walk(path Path, visit Visit) { + self.SHACLObjectBase.Walk(path, visit) +} + + + +func (self *EnumTypeObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.SHACLObjectBase.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// An extensible abstract class +type ExtensibleAbstractClassObject struct { + SHACLObjectBase + SHACLExtensibleBase + +} + + +type ExtensibleAbstractClassObjectType struct { + SHACLTypeBase +} +var extensibleAbstractClassType ExtensibleAbstractClassObjectType + +func DecodeExtensibleAbstractClass (data any, path Path, context map[string]string) (Ref[ExtensibleAbstractClass], error) { + return DecodeRef[ExtensibleAbstractClass](data, path, context, extensibleAbstractClassType) +} + +func (self ExtensibleAbstractClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(ExtensibleAbstractClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self ExtensibleAbstractClassObjectType) Create() SHACLObject { + return ConstructExtensibleAbstractClassObject(&ExtensibleAbstractClassObject{}, self) +} + +func ConstructExtensibleAbstractClassObject(o *ExtensibleAbstractClassObject, typ SHACLType) *ExtensibleAbstractClassObject { + ConstructSHACLObjectBase(&o.SHACLObjectBase, typ) + return o +} + +type ExtensibleAbstractClass interface { + SHACLObject +} + + + +func (self *ExtensibleAbstractClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.SHACLObjectBase.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *ExtensibleAbstractClassObject) Walk(path Path, visit Visit) { + self.SHACLObjectBase.Walk(path, visit) +} + + + +func (self *ExtensibleAbstractClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.SHACLObjectBase.EncodeProperties(data, path, state); err != nil { + return err + } + self.SHACLExtensibleBase.EncodeExtProperties(data, path) + return nil +} + +// A class with an ID alias +type IdPropClassObject struct { + SHACLObjectBase + +} + + +type IdPropClassObjectType struct { + SHACLTypeBase +} +var idPropClassType IdPropClassObjectType + +func DecodeIdPropClass (data any, path Path, context map[string]string) (Ref[IdPropClass], error) { + return DecodeRef[IdPropClass](data, path, context, idPropClassType) +} + +func (self IdPropClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(IdPropClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self IdPropClassObjectType) Create() SHACLObject { + return ConstructIdPropClassObject(&IdPropClassObject{}, self) +} + +func ConstructIdPropClassObject(o *IdPropClassObject, typ SHACLType) *IdPropClassObject { + ConstructSHACLObjectBase(&o.SHACLObjectBase, typ) + return o +} + +type IdPropClass interface { + SHACLObject +} + + +func MakeIdPropClass() IdPropClass { + return ConstructIdPropClassObject(&IdPropClassObject{}, idPropClassType) +} + +func MakeIdPropClassRef() Ref[IdPropClass] { + o := MakeIdPropClass() + return MakeObjectRef[IdPropClass](o) +} + +func (self *IdPropClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.SHACLObjectBase.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *IdPropClassObject) Walk(path Path, visit Visit) { + self.SHACLObjectBase.Walk(path, visit) +} + + + +func (self *IdPropClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.SHACLObjectBase.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// A class that inherits its idPropertyName from the parent +type InheritedIdPropClassObject struct { + IdPropClassObject + +} + + +type InheritedIdPropClassObjectType struct { + SHACLTypeBase +} +var inheritedIdPropClassType InheritedIdPropClassObjectType + +func DecodeInheritedIdPropClass (data any, path Path, context map[string]string) (Ref[InheritedIdPropClass], error) { + return DecodeRef[InheritedIdPropClass](data, path, context, inheritedIdPropClassType) +} + +func (self InheritedIdPropClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(InheritedIdPropClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self InheritedIdPropClassObjectType) Create() SHACLObject { + return ConstructInheritedIdPropClassObject(&InheritedIdPropClassObject{}, self) +} + +func ConstructInheritedIdPropClassObject(o *InheritedIdPropClassObject, typ SHACLType) *InheritedIdPropClassObject { + ConstructIdPropClassObject(&o.IdPropClassObject, typ) + return o +} + +type InheritedIdPropClass interface { + IdPropClass +} + + +func MakeInheritedIdPropClass() InheritedIdPropClass { + return ConstructInheritedIdPropClassObject(&InheritedIdPropClassObject{}, inheritedIdPropClassType) +} + +func MakeInheritedIdPropClassRef() Ref[InheritedIdPropClass] { + o := MakeInheritedIdPropClass() + return MakeObjectRef[InheritedIdPropClass](o) +} + +func (self *InheritedIdPropClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.IdPropClassObject.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *InheritedIdPropClassObject) Walk(path Path, visit Visit) { + self.IdPropClassObject.Walk(path, visit) +} + + + +func (self *InheritedIdPropClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.IdPropClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// A class to test links +type LinkClassObject struct { + SHACLObjectBase + + // A link to an extensible-class + linkClassExtensible RefProperty[ExtensibleClass] + // A link-class list property + linkClassLinkListProp RefListProperty[LinkClass] + // A link-class property + linkClassLinkProp RefProperty[LinkClass] + // A link-class property with no sh:class + linkClassLinkPropNoClass RefProperty[LinkClass] +} + + +type LinkClassObjectType struct { + SHACLTypeBase +} +var linkClassType LinkClassObjectType +var linkClassLinkClassExtensibleContext = map[string]string{} +var linkClassLinkClassLinkListPropContext = map[string]string{} +var linkClassLinkClassLinkPropContext = map[string]string{} +var linkClassLinkClassLinkPropNoClassContext = map[string]string{} + +func DecodeLinkClass (data any, path Path, context map[string]string) (Ref[LinkClass], error) { + return DecodeRef[LinkClass](data, path, context, linkClassType) +} + +func (self LinkClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(LinkClass) + _ = obj + switch name { + case "http://example.org/link-class-extensible", "link-class-extensible": + val, err := DecodeExtensibleClass(value, path, linkClassLinkClassExtensibleContext) + if err != nil { + return false, err + } + err = obj.LinkClassExtensible().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/link-class-link-list-prop", "link-class-link-list-prop": + val, err := DecodeList[Ref[LinkClass]](value, path, linkClassLinkClassLinkListPropContext, DecodeLinkClass) + if err != nil { + return false, err + } + err = obj.LinkClassLinkListProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/link-class-link-prop", "link-class-link-prop": + val, err := DecodeLinkClass(value, path, linkClassLinkClassLinkPropContext) + if err != nil { + return false, err + } + err = obj.LinkClassLinkProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/link-class-link-prop-no-class", "link-class-link-prop-no-class": + val, err := DecodeLinkClass(value, path, linkClassLinkClassLinkPropNoClassContext) + if err != nil { + return false, err + } + err = obj.LinkClassLinkPropNoClass().Set(val) + if err != nil { + return false, err + } + return true, nil + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self LinkClassObjectType) Create() SHACLObject { + return ConstructLinkClassObject(&LinkClassObject{}, self) +} + +func ConstructLinkClassObject(o *LinkClassObject, typ SHACLType) *LinkClassObject { + ConstructSHACLObjectBase(&o.SHACLObjectBase, typ) + { + validators := []Validator[Ref[ExtensibleClass]]{} + o.linkClassExtensible = NewRefProperty[ExtensibleClass]("linkClassExtensible", validators) + } + { + validators := []Validator[Ref[LinkClass]]{} + o.linkClassLinkListProp = NewRefListProperty[LinkClass]("linkClassLinkListProp", validators) + } + { + validators := []Validator[Ref[LinkClass]]{} + o.linkClassLinkProp = NewRefProperty[LinkClass]("linkClassLinkProp", validators) + } + { + validators := []Validator[Ref[LinkClass]]{} + o.linkClassLinkPropNoClass = NewRefProperty[LinkClass]("linkClassLinkPropNoClass", validators) + } + return o +} + +type LinkClass interface { + SHACLObject + LinkClassExtensible() RefPropertyInterface[ExtensibleClass] + LinkClassLinkListProp() ListPropertyInterface[Ref[LinkClass]] + LinkClassLinkProp() RefPropertyInterface[LinkClass] + LinkClassLinkPropNoClass() RefPropertyInterface[LinkClass] +} + + +func MakeLinkClass() LinkClass { + return ConstructLinkClassObject(&LinkClassObject{}, linkClassType) +} + +func MakeLinkClassRef() Ref[LinkClass] { + o := MakeLinkClass() + return MakeObjectRef[LinkClass](o) +} + +func (self *LinkClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.SHACLObjectBase.Validate(path, handler) { + valid = false + } + { + prop_path := path.PushPath("linkClassExtensible") + if ! self.linkClassExtensible.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("linkClassLinkListProp") + if ! self.linkClassLinkListProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("linkClassLinkProp") + if ! self.linkClassLinkProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("linkClassLinkPropNoClass") + if ! self.linkClassLinkPropNoClass.Check(prop_path, handler) { + valid = false + } + } + return valid +} + +func (self *LinkClassObject) Walk(path Path, visit Visit) { + self.SHACLObjectBase.Walk(path, visit) + self.linkClassExtensible.Walk(path, visit) + self.linkClassLinkListProp.Walk(path, visit) + self.linkClassLinkProp.Walk(path, visit) + self.linkClassLinkPropNoClass.Walk(path, visit) +} + + +func (self *LinkClassObject) LinkClassExtensible() RefPropertyInterface[ExtensibleClass] { return &self.linkClassExtensible } +func (self *LinkClassObject) LinkClassLinkListProp() ListPropertyInterface[Ref[LinkClass]] { return &self.linkClassLinkListProp } +func (self *LinkClassObject) LinkClassLinkProp() RefPropertyInterface[LinkClass] { return &self.linkClassLinkProp } +func (self *LinkClassObject) LinkClassLinkPropNoClass() RefPropertyInterface[LinkClass] { return &self.linkClassLinkPropNoClass } + +func (self *LinkClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.SHACLObjectBase.EncodeProperties(data, path, state); err != nil { + return err + } + if self.linkClassExtensible.IsSet() { + val, err := EncodeRef[ExtensibleClass](self.linkClassExtensible.Get(), path.PushPath("linkClassExtensible"), linkClassLinkClassExtensibleContext, state) + if err != nil { + return err + } + data["link-class-extensible"] = val + } + if self.linkClassLinkListProp.IsSet() { + val, err := EncodeList[Ref[LinkClass]](self.linkClassLinkListProp.Get(), path.PushPath("linkClassLinkListProp"), linkClassLinkClassLinkListPropContext, state, EncodeRef[LinkClass]) + if err != nil { + return err + } + data["link-class-link-list-prop"] = val + } + if self.linkClassLinkProp.IsSet() { + val, err := EncodeRef[LinkClass](self.linkClassLinkProp.Get(), path.PushPath("linkClassLinkProp"), linkClassLinkClassLinkPropContext, state) + if err != nil { + return err + } + data["link-class-link-prop"] = val + } + if self.linkClassLinkPropNoClass.IsSet() { + val, err := EncodeRef[LinkClass](self.linkClassLinkPropNoClass.Get(), path.PushPath("linkClassLinkPropNoClass"), linkClassLinkClassLinkPropNoClassContext, state) + if err != nil { + return err + } + data["link-class-link-prop-no-class"] = val + } + return nil +} + +// A class derived from link-class +type LinkDerivedClassObject struct { + LinkClassObject + +} + + +type LinkDerivedClassObjectType struct { + SHACLTypeBase +} +var linkDerivedClassType LinkDerivedClassObjectType + +func DecodeLinkDerivedClass (data any, path Path, context map[string]string) (Ref[LinkDerivedClass], error) { + return DecodeRef[LinkDerivedClass](data, path, context, linkDerivedClassType) +} + +func (self LinkDerivedClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(LinkDerivedClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self LinkDerivedClassObjectType) Create() SHACLObject { + return ConstructLinkDerivedClassObject(&LinkDerivedClassObject{}, self) +} + +func ConstructLinkDerivedClassObject(o *LinkDerivedClassObject, typ SHACLType) *LinkDerivedClassObject { + ConstructLinkClassObject(&o.LinkClassObject, typ) + return o +} + +type LinkDerivedClass interface { + LinkClass +} + + +func MakeLinkDerivedClass() LinkDerivedClass { + return ConstructLinkDerivedClassObject(&LinkDerivedClassObject{}, linkDerivedClassType) +} + +func MakeLinkDerivedClassRef() Ref[LinkDerivedClass] { + o := MakeLinkDerivedClass() + return MakeObjectRef[LinkDerivedClass](o) +} + +func (self *LinkDerivedClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.LinkClassObject.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *LinkDerivedClassObject) Walk(path Path, visit Visit) { + self.LinkClassObject.Walk(path, visit) +} + + + +func (self *LinkDerivedClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.LinkClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// A class that must be a blank node +type NodeKindBlankObject struct { + LinkClassObject + +} + + +type NodeKindBlankObjectType struct { + SHACLTypeBase +} +var nodeKindBlankType NodeKindBlankObjectType + +func DecodeNodeKindBlank (data any, path Path, context map[string]string) (Ref[NodeKindBlank], error) { + return DecodeRef[NodeKindBlank](data, path, context, nodeKindBlankType) +} + +func (self NodeKindBlankObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(NodeKindBlank) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self NodeKindBlankObjectType) Create() SHACLObject { + return ConstructNodeKindBlankObject(&NodeKindBlankObject{}, self) +} + +func ConstructNodeKindBlankObject(o *NodeKindBlankObject, typ SHACLType) *NodeKindBlankObject { + ConstructLinkClassObject(&o.LinkClassObject, typ) + return o +} + +type NodeKindBlank interface { + LinkClass +} + + +func MakeNodeKindBlank() NodeKindBlank { + return ConstructNodeKindBlankObject(&NodeKindBlankObject{}, nodeKindBlankType) +} + +func MakeNodeKindBlankRef() Ref[NodeKindBlank] { + o := MakeNodeKindBlank() + return MakeObjectRef[NodeKindBlank](o) +} + +func (self *NodeKindBlankObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.LinkClassObject.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *NodeKindBlankObject) Walk(path Path, visit Visit) { + self.LinkClassObject.Walk(path, visit) +} + + + +func (self *NodeKindBlankObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.LinkClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// A class that must be an IRI +type NodeKindIriObject struct { + LinkClassObject + +} + + +type NodeKindIriObjectType struct { + SHACLTypeBase +} +var nodeKindIriType NodeKindIriObjectType + +func DecodeNodeKindIri (data any, path Path, context map[string]string) (Ref[NodeKindIri], error) { + return DecodeRef[NodeKindIri](data, path, context, nodeKindIriType) +} + +func (self NodeKindIriObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(NodeKindIri) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self NodeKindIriObjectType) Create() SHACLObject { + return ConstructNodeKindIriObject(&NodeKindIriObject{}, self) +} + +func ConstructNodeKindIriObject(o *NodeKindIriObject, typ SHACLType) *NodeKindIriObject { + ConstructLinkClassObject(&o.LinkClassObject, typ) + return o +} + +type NodeKindIri interface { + LinkClass +} + + +func MakeNodeKindIri() NodeKindIri { + return ConstructNodeKindIriObject(&NodeKindIriObject{}, nodeKindIriType) +} + +func MakeNodeKindIriRef() Ref[NodeKindIri] { + o := MakeNodeKindIri() + return MakeObjectRef[NodeKindIri](o) +} + +func (self *NodeKindIriObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.LinkClassObject.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *NodeKindIriObject) Walk(path Path, visit Visit) { + self.LinkClassObject.Walk(path, visit) +} + + + +func (self *NodeKindIriObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.LinkClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// A class that can be either a blank node or an IRI +type NodeKindIriOrBlankObject struct { + LinkClassObject + +} + + +type NodeKindIriOrBlankObjectType struct { + SHACLTypeBase +} +var nodeKindIriOrBlankType NodeKindIriOrBlankObjectType + +func DecodeNodeKindIriOrBlank (data any, path Path, context map[string]string) (Ref[NodeKindIriOrBlank], error) { + return DecodeRef[NodeKindIriOrBlank](data, path, context, nodeKindIriOrBlankType) +} + +func (self NodeKindIriOrBlankObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(NodeKindIriOrBlank) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self NodeKindIriOrBlankObjectType) Create() SHACLObject { + return ConstructNodeKindIriOrBlankObject(&NodeKindIriOrBlankObject{}, self) +} + +func ConstructNodeKindIriOrBlankObject(o *NodeKindIriOrBlankObject, typ SHACLType) *NodeKindIriOrBlankObject { + ConstructLinkClassObject(&o.LinkClassObject, typ) + return o +} + +type NodeKindIriOrBlank interface { + LinkClass +} + + +func MakeNodeKindIriOrBlank() NodeKindIriOrBlank { + return ConstructNodeKindIriOrBlankObject(&NodeKindIriOrBlankObject{}, nodeKindIriOrBlankType) +} + +func MakeNodeKindIriOrBlankRef() Ref[NodeKindIriOrBlank] { + o := MakeNodeKindIriOrBlank() + return MakeObjectRef[NodeKindIriOrBlank](o) +} + +func (self *NodeKindIriOrBlankObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.LinkClassObject.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *NodeKindIriOrBlankObject) Walk(path Path, visit Visit) { + self.LinkClassObject.Walk(path, visit) +} + + + +func (self *NodeKindIriOrBlankObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.LinkClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// A class that is not a nodeshape +type NonShapeClassObject struct { + SHACLObjectBase + +} + + +type NonShapeClassObjectType struct { + SHACLTypeBase +} +var nonShapeClassType NonShapeClassObjectType + +func DecodeNonShapeClass (data any, path Path, context map[string]string) (Ref[NonShapeClass], error) { + return DecodeRef[NonShapeClass](data, path, context, nonShapeClassType) +} + +func (self NonShapeClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(NonShapeClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self NonShapeClassObjectType) Create() SHACLObject { + return ConstructNonShapeClassObject(&NonShapeClassObject{}, self) +} + +func ConstructNonShapeClassObject(o *NonShapeClassObject, typ SHACLType) *NonShapeClassObject { + ConstructSHACLObjectBase(&o.SHACLObjectBase, typ) + return o +} + +type NonShapeClass interface { + SHACLObject +} + + +func MakeNonShapeClass() NonShapeClass { + return ConstructNonShapeClassObject(&NonShapeClassObject{}, nonShapeClassType) +} + +func MakeNonShapeClassRef() Ref[NonShapeClass] { + o := MakeNonShapeClass() + return MakeObjectRef[NonShapeClass](o) +} + +func (self *NonShapeClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.SHACLObjectBase.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *NonShapeClassObject) Walk(path Path, visit Visit) { + self.SHACLObjectBase.Walk(path, visit) +} + + + +func (self *NonShapeClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.SHACLObjectBase.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// The parent class +type ParentClassObject struct { + SHACLObjectBase + +} + + +type ParentClassObjectType struct { + SHACLTypeBase +} +var parentClassType ParentClassObjectType + +func DecodeParentClass (data any, path Path, context map[string]string) (Ref[ParentClass], error) { + return DecodeRef[ParentClass](data, path, context, parentClassType) +} + +func (self ParentClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(ParentClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self ParentClassObjectType) Create() SHACLObject { + return ConstructParentClassObject(&ParentClassObject{}, self) +} + +func ConstructParentClassObject(o *ParentClassObject, typ SHACLType) *ParentClassObject { + ConstructSHACLObjectBase(&o.SHACLObjectBase, typ) + return o +} + +type ParentClass interface { + SHACLObject +} + + +func MakeParentClass() ParentClass { + return ConstructParentClassObject(&ParentClassObject{}, parentClassType) +} + +func MakeParentClassRef() Ref[ParentClass] { + o := MakeParentClass() + return MakeObjectRef[ParentClass](o) +} + +func (self *ParentClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.SHACLObjectBase.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *ParentClassObject) Walk(path Path, visit Visit) { + self.SHACLObjectBase.Walk(path, visit) +} + + + +func (self *ParentClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.SHACLObjectBase.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// A class with a mandatory abstract class +type RequiredAbstractObject struct { + SHACLObjectBase + + // A required abstract class property + requiredAbstractAbstractClassProp RefProperty[AbstractClass] +} + + +type RequiredAbstractObjectType struct { + SHACLTypeBase +} +var requiredAbstractType RequiredAbstractObjectType +var requiredAbstractRequiredAbstractAbstractClassPropContext = map[string]string{} + +func DecodeRequiredAbstract (data any, path Path, context map[string]string) (Ref[RequiredAbstract], error) { + return DecodeRef[RequiredAbstract](data, path, context, requiredAbstractType) +} + +func (self RequiredAbstractObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(RequiredAbstract) + _ = obj + switch name { + case "http://example.org/required-abstract/abstract-class-prop", "required-abstract/abstract-class-prop": + val, err := DecodeAbstractClass(value, path, requiredAbstractRequiredAbstractAbstractClassPropContext) + if err != nil { + return false, err + } + err = obj.RequiredAbstractAbstractClassProp().Set(val) + if err != nil { + return false, err + } + return true, nil + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self RequiredAbstractObjectType) Create() SHACLObject { + return ConstructRequiredAbstractObject(&RequiredAbstractObject{}, self) +} + +func ConstructRequiredAbstractObject(o *RequiredAbstractObject, typ SHACLType) *RequiredAbstractObject { + ConstructSHACLObjectBase(&o.SHACLObjectBase, typ) + { + validators := []Validator[Ref[AbstractClass]]{} + o.requiredAbstractAbstractClassProp = NewRefProperty[AbstractClass]("requiredAbstractAbstractClassProp", validators) + } + return o +} + +type RequiredAbstract interface { + SHACLObject + RequiredAbstractAbstractClassProp() RefPropertyInterface[AbstractClass] +} + + +func MakeRequiredAbstract() RequiredAbstract { + return ConstructRequiredAbstractObject(&RequiredAbstractObject{}, requiredAbstractType) +} + +func MakeRequiredAbstractRef() Ref[RequiredAbstract] { + o := MakeRequiredAbstract() + return MakeObjectRef[RequiredAbstract](o) +} + +func (self *RequiredAbstractObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.SHACLObjectBase.Validate(path, handler) { + valid = false + } + { + prop_path := path.PushPath("requiredAbstractAbstractClassProp") + if ! self.requiredAbstractAbstractClassProp.Check(prop_path, handler) { + valid = false + } + if ! self.requiredAbstractAbstractClassProp.IsSet() { + if handler != nil { + handler.HandleError(&ValidationError{"requiredAbstractAbstractClassProp", "Value is required"}, prop_path) + } + valid = false + } + } + return valid +} + +func (self *RequiredAbstractObject) Walk(path Path, visit Visit) { + self.SHACLObjectBase.Walk(path, visit) + self.requiredAbstractAbstractClassProp.Walk(path, visit) +} + + +func (self *RequiredAbstractObject) RequiredAbstractAbstractClassProp() RefPropertyInterface[AbstractClass] { return &self.requiredAbstractAbstractClassProp } + +func (self *RequiredAbstractObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.SHACLObjectBase.EncodeProperties(data, path, state); err != nil { + return err + } + if self.requiredAbstractAbstractClassProp.IsSet() { + val, err := EncodeRef[AbstractClass](self.requiredAbstractAbstractClassProp.Get(), path.PushPath("requiredAbstractAbstractClassProp"), requiredAbstractRequiredAbstractAbstractClassPropContext, state) + if err != nil { + return err + } + data["required-abstract/abstract-class-prop"] = val + } + return nil +} + +// Another class +type TestAnotherClassObject struct { + SHACLObjectBase + +} + + +type TestAnotherClassObjectType struct { + SHACLTypeBase +} +var testAnotherClassType TestAnotherClassObjectType + +func DecodeTestAnotherClass (data any, path Path, context map[string]string) (Ref[TestAnotherClass], error) { + return DecodeRef[TestAnotherClass](data, path, context, testAnotherClassType) +} + +func (self TestAnotherClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(TestAnotherClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self TestAnotherClassObjectType) Create() SHACLObject { + return ConstructTestAnotherClassObject(&TestAnotherClassObject{}, self) +} + +func ConstructTestAnotherClassObject(o *TestAnotherClassObject, typ SHACLType) *TestAnotherClassObject { + ConstructSHACLObjectBase(&o.SHACLObjectBase, typ) + return o +} + +type TestAnotherClass interface { + SHACLObject +} + + +func MakeTestAnotherClass() TestAnotherClass { + return ConstructTestAnotherClassObject(&TestAnotherClassObject{}, testAnotherClassType) +} + +func MakeTestAnotherClassRef() Ref[TestAnotherClass] { + o := MakeTestAnotherClass() + return MakeObjectRef[TestAnotherClass](o) +} + +func (self *TestAnotherClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.SHACLObjectBase.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *TestAnotherClassObject) Walk(path Path, visit Visit) { + self.SHACLObjectBase.Walk(path, visit) +} + + + +func (self *TestAnotherClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.SHACLObjectBase.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// The test class +type TestClassObject struct { + ParentClassObject + + // A property that conflicts with an existing SHACLObject property + encode Property[string] + // A property that is a keyword + import_ Property[string] + // a URI + testClassAnyuriProp Property[string] + // a boolean property + testClassBooleanProp Property[bool] + // A test-class list property + testClassClassListProp RefListProperty[TestClass] + // A test-class property + testClassClassProp RefProperty[TestClass] + // A test-class property with no sh:class + testClassClassPropNoClass RefProperty[TestClass] + // A datetime list property + testClassDatetimeListProp ListProperty[time.Time] + // A scalar datetime property + testClassDatetimeScalarProp Property[time.Time] + // A scalar dateTimeStamp property + testClassDatetimestampScalarProp Property[time.Time] + // A enum list property + testClassEnumListProp ListProperty[string] + // A enum property + testClassEnumProp Property[string] + // A enum property with no sh:class + testClassEnumPropNoClass Property[string] + // a float property + testClassFloatProp Property[float64] + // a non-negative integer + testClassIntegerProp Property[int] + // A named property + namedProperty Property[string] + // A class with no shape + testClassNonShape RefProperty[NonShapeClass] + // a non-negative integer + testClassNonnegativeIntegerProp Property[int] + // A positive integer + testClassPositiveIntegerProp Property[int] + // A regex validated string + testClassRegex Property[string] + // A regex dateTime + testClassRegexDatetime Property[time.Time] + // A regex dateTimeStamp + testClassRegexDatetimestamp Property[time.Time] + // A regex validated string list + testClassRegexList ListProperty[string] + // A string list property with no sh:datatype + testClassStringListNoDatatype ListProperty[string] + // A string list property + testClassStringListProp ListProperty[string] + // A scalar string propery + testClassStringScalarProp Property[string] +} +const TestClassNamed = "http://example.org/test-class/named" + +type TestClassObjectType struct { + SHACLTypeBase +} +var testClassType TestClassObjectType +var testClassEncodeContext = map[string]string{} +var testClassImportContext = map[string]string{} +var testClassTestClassAnyuriPropContext = map[string]string{} +var testClassTestClassBooleanPropContext = map[string]string{} +var testClassTestClassClassListPropContext = map[string]string{ + "http://example.org/test-class/named": "named",} +var testClassTestClassClassPropContext = map[string]string{ + "http://example.org/test-class/named": "named",} +var testClassTestClassClassPropNoClassContext = map[string]string{ + "http://example.org/test-class/named": "named",} +var testClassTestClassDatetimeListPropContext = map[string]string{} +var testClassTestClassDatetimeScalarPropContext = map[string]string{} +var testClassTestClassDatetimestampScalarPropContext = map[string]string{} +var testClassTestClassEnumListPropContext = map[string]string{ + "http://example.org/enumType/bar": "bar", + "http://example.org/enumType/foo": "foo", + "http://example.org/enumType/nolabel": "nolabel", + "http://example.org/enumType/non-named-individual": "non-named-individual",} +var testClassTestClassEnumPropContext = map[string]string{ + "http://example.org/enumType/bar": "bar", + "http://example.org/enumType/foo": "foo", + "http://example.org/enumType/nolabel": "nolabel", + "http://example.org/enumType/non-named-individual": "non-named-individual",} +var testClassTestClassEnumPropNoClassContext = map[string]string{ + "http://example.org/enumType/bar": "bar", + "http://example.org/enumType/foo": "foo", + "http://example.org/enumType/nolabel": "nolabel", + "http://example.org/enumType/non-named-individual": "non-named-individual",} +var testClassTestClassFloatPropContext = map[string]string{} +var testClassTestClassIntegerPropContext = map[string]string{} +var testClassNamedPropertyContext = map[string]string{} +var testClassTestClassNonShapeContext = map[string]string{} +var testClassTestClassNonnegativeIntegerPropContext = map[string]string{} +var testClassTestClassPositiveIntegerPropContext = map[string]string{} +var testClassTestClassRegexContext = map[string]string{} +var testClassTestClassRegexDatetimeContext = map[string]string{} +var testClassTestClassRegexDatetimestampContext = map[string]string{} +var testClassTestClassRegexListContext = map[string]string{} +var testClassTestClassStringListNoDatatypeContext = map[string]string{} +var testClassTestClassStringListPropContext = map[string]string{} +var testClassTestClassStringScalarPropContext = map[string]string{} + +func DecodeTestClass (data any, path Path, context map[string]string) (Ref[TestClass], error) { + return DecodeRef[TestClass](data, path, context, testClassType) +} + +func (self TestClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(TestClass) + _ = obj + switch name { + case "http://example.org/encode", "encode": + val, err := DecodeString(value, path, testClassEncodeContext) + if err != nil { + return false, err + } + err = obj.Encode().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/import", "import": + val, err := DecodeString(value, path, testClassImportContext) + if err != nil { + return false, err + } + err = obj.Import().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/anyuri-prop", "test-class/anyuri-prop": + val, err := DecodeString(value, path, testClassTestClassAnyuriPropContext) + if err != nil { + return false, err + } + err = obj.TestClassAnyuriProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/boolean-prop", "test-class/boolean-prop": + val, err := DecodeBoolean(value, path, testClassTestClassBooleanPropContext) + if err != nil { + return false, err + } + err = obj.TestClassBooleanProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/class-list-prop", "test-class/class-list-prop": + val, err := DecodeList[Ref[TestClass]](value, path, testClassTestClassClassListPropContext, DecodeTestClass) + if err != nil { + return false, err + } + err = obj.TestClassClassListProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/class-prop", "test-class/class-prop": + val, err := DecodeTestClass(value, path, testClassTestClassClassPropContext) + if err != nil { + return false, err + } + err = obj.TestClassClassProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/class-prop-no-class", "test-class/class-prop-no-class": + val, err := DecodeTestClass(value, path, testClassTestClassClassPropNoClassContext) + if err != nil { + return false, err + } + err = obj.TestClassClassPropNoClass().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/datetime-list-prop", "test-class/datetime-list-prop": + val, err := DecodeList[time.Time](value, path, testClassTestClassDatetimeListPropContext, DecodeDateTime) + if err != nil { + return false, err + } + err = obj.TestClassDatetimeListProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/datetime-scalar-prop", "test-class/datetime-scalar-prop": + val, err := DecodeDateTime(value, path, testClassTestClassDatetimeScalarPropContext) + if err != nil { + return false, err + } + err = obj.TestClassDatetimeScalarProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/datetimestamp-scalar-prop", "test-class/datetimestamp-scalar-prop": + val, err := DecodeDateTimeStamp(value, path, testClassTestClassDatetimestampScalarPropContext) + if err != nil { + return false, err + } + err = obj.TestClassDatetimestampScalarProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/enum-list-prop", "test-class/enum-list-prop": + val, err := DecodeList[string](value, path, testClassTestClassEnumListPropContext, DecodeIRI) + if err != nil { + return false, err + } + err = obj.TestClassEnumListProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/enum-prop", "test-class/enum-prop": + val, err := DecodeIRI(value, path, testClassTestClassEnumPropContext) + if err != nil { + return false, err + } + err = obj.TestClassEnumProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/enum-prop-no-class", "test-class/enum-prop-no-class": + val, err := DecodeIRI(value, path, testClassTestClassEnumPropNoClassContext) + if err != nil { + return false, err + } + err = obj.TestClassEnumPropNoClass().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/float-prop", "test-class/float-prop": + val, err := DecodeFloat(value, path, testClassTestClassFloatPropContext) + if err != nil { + return false, err + } + err = obj.TestClassFloatProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/integer-prop", "test-class/integer-prop": + val, err := DecodeInteger(value, path, testClassTestClassIntegerPropContext) + if err != nil { + return false, err + } + err = obj.TestClassIntegerProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/named-property", "test-class/named-property": + val, err := DecodeString(value, path, testClassNamedPropertyContext) + if err != nil { + return false, err + } + err = obj.NamedProperty().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/non-shape", "test-class/non-shape": + val, err := DecodeNonShapeClass(value, path, testClassTestClassNonShapeContext) + if err != nil { + return false, err + } + err = obj.TestClassNonShape().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/nonnegative-integer-prop", "test-class/nonnegative-integer-prop": + val, err := DecodeInteger(value, path, testClassTestClassNonnegativeIntegerPropContext) + if err != nil { + return false, err + } + err = obj.TestClassNonnegativeIntegerProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/positive-integer-prop", "test-class/positive-integer-prop": + val, err := DecodeInteger(value, path, testClassTestClassPositiveIntegerPropContext) + if err != nil { + return false, err + } + err = obj.TestClassPositiveIntegerProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/regex", "test-class/regex": + val, err := DecodeString(value, path, testClassTestClassRegexContext) + if err != nil { + return false, err + } + err = obj.TestClassRegex().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/regex-datetime", "test-class/regex-datetime": + val, err := DecodeDateTime(value, path, testClassTestClassRegexDatetimeContext) + if err != nil { + return false, err + } + err = obj.TestClassRegexDatetime().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/regex-datetimestamp", "test-class/regex-datetimestamp": + val, err := DecodeDateTimeStamp(value, path, testClassTestClassRegexDatetimestampContext) + if err != nil { + return false, err + } + err = obj.TestClassRegexDatetimestamp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/regex-list", "test-class/regex-list": + val, err := DecodeList[string](value, path, testClassTestClassRegexListContext, DecodeString) + if err != nil { + return false, err + } + err = obj.TestClassRegexList().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/string-list-no-datatype", "test-class/string-list-no-datatype": + val, err := DecodeList[string](value, path, testClassTestClassStringListNoDatatypeContext, DecodeString) + if err != nil { + return false, err + } + err = obj.TestClassStringListNoDatatype().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/string-list-prop", "test-class/string-list-prop": + val, err := DecodeList[string](value, path, testClassTestClassStringListPropContext, DecodeString) + if err != nil { + return false, err + } + err = obj.TestClassStringListProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/string-scalar-prop", "test-class/string-scalar-prop": + val, err := DecodeString(value, path, testClassTestClassStringScalarPropContext) + if err != nil { + return false, err + } + err = obj.TestClassStringScalarProp().Set(val) + if err != nil { + return false, err + } + return true, nil + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self TestClassObjectType) Create() SHACLObject { + return ConstructTestClassObject(&TestClassObject{}, self) +} + +func ConstructTestClassObject(o *TestClassObject, typ SHACLType) *TestClassObject { + ConstructParentClassObject(&o.ParentClassObject, typ) + { + validators := []Validator[string]{} + o.encode = NewProperty[string]("encode", validators) + } + { + validators := []Validator[string]{} + o.import_ = NewProperty[string]("import_", validators) + } + { + validators := []Validator[string]{} + o.testClassAnyuriProp = NewProperty[string]("testClassAnyuriProp", validators) + } + { + validators := []Validator[bool]{} + o.testClassBooleanProp = NewProperty[bool]("testClassBooleanProp", validators) + } + { + validators := []Validator[Ref[TestClass]]{} + o.testClassClassListProp = NewRefListProperty[TestClass]("testClassClassListProp", validators) + } + { + validators := []Validator[Ref[TestClass]]{} + o.testClassClassProp = NewRefProperty[TestClass]("testClassClassProp", validators) + } + { + validators := []Validator[Ref[TestClass]]{} + o.testClassClassPropNoClass = NewRefProperty[TestClass]("testClassClassPropNoClass", validators) + } + { + validators := []Validator[time.Time]{} + o.testClassDatetimeListProp = NewListProperty[time.Time]("testClassDatetimeListProp", validators) + } + { + validators := []Validator[time.Time]{} + o.testClassDatetimeScalarProp = NewProperty[time.Time]("testClassDatetimeScalarProp", validators) + } + { + validators := []Validator[time.Time]{} + o.testClassDatetimestampScalarProp = NewProperty[time.Time]("testClassDatetimestampScalarProp", validators) + } + { + validators := []Validator[string]{} + validators = append(validators, + EnumValidator{[]string{ + "http://example.org/enumType/bar", + "http://example.org/enumType/foo", + "http://example.org/enumType/nolabel", + "http://example.org/enumType/non-named-individual", + }}) + o.testClassEnumListProp = NewListProperty[string]("testClassEnumListProp", validators) + } + { + validators := []Validator[string]{} + validators = append(validators, + EnumValidator{[]string{ + "http://example.org/enumType/bar", + "http://example.org/enumType/foo", + "http://example.org/enumType/nolabel", + "http://example.org/enumType/non-named-individual", + }}) + o.testClassEnumProp = NewProperty[string]("testClassEnumProp", validators) + } + { + validators := []Validator[string]{} + validators = append(validators, + EnumValidator{[]string{ + "http://example.org/enumType/bar", + "http://example.org/enumType/foo", + "http://example.org/enumType/nolabel", + "http://example.org/enumType/non-named-individual", + }}) + o.testClassEnumPropNoClass = NewProperty[string]("testClassEnumPropNoClass", validators) + } + { + validators := []Validator[float64]{} + o.testClassFloatProp = NewProperty[float64]("testClassFloatProp", validators) + } + { + validators := []Validator[int]{} + o.testClassIntegerProp = NewProperty[int]("testClassIntegerProp", validators) + } + { + validators := []Validator[string]{} + o.namedProperty = NewProperty[string]("namedProperty", validators) + } + { + validators := []Validator[Ref[NonShapeClass]]{} + o.testClassNonShape = NewRefProperty[NonShapeClass]("testClassNonShape", validators) + } + { + validators := []Validator[int]{} + validators = append(validators, IntegerMinValidator{0}) + o.testClassNonnegativeIntegerProp = NewProperty[int]("testClassNonnegativeIntegerProp", validators) + } + { + validators := []Validator[int]{} + validators = append(validators, IntegerMinValidator{1}) + o.testClassPositiveIntegerProp = NewProperty[int]("testClassPositiveIntegerProp", validators) + } + { + validators := []Validator[string]{} + validators = append(validators, RegexValidator[string]{`^foo\d`}) + o.testClassRegex = NewProperty[string]("testClassRegex", validators) + } + { + validators := []Validator[time.Time]{} + validators = append(validators, RegexValidator[time.Time]{`^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d\+01:00$`}) + o.testClassRegexDatetime = NewProperty[time.Time]("testClassRegexDatetime", validators) + } + { + validators := []Validator[time.Time]{} + validators = append(validators, RegexValidator[time.Time]{`^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\dZ$`}) + o.testClassRegexDatetimestamp = NewProperty[time.Time]("testClassRegexDatetimestamp", validators) + } + { + validators := []Validator[string]{} + validators = append(validators, RegexValidator[string]{`^foo\d`}) + o.testClassRegexList = NewListProperty[string]("testClassRegexList", validators) + } + { + validators := []Validator[string]{} + o.testClassStringListNoDatatype = NewListProperty[string]("testClassStringListNoDatatype", validators) + } + { + validators := []Validator[string]{} + o.testClassStringListProp = NewListProperty[string]("testClassStringListProp", validators) + } + { + validators := []Validator[string]{} + o.testClassStringScalarProp = NewProperty[string]("testClassStringScalarProp", validators) + } + return o +} + +type TestClass interface { + ParentClass + Encode() PropertyInterface[string] + Import() PropertyInterface[string] + TestClassAnyuriProp() PropertyInterface[string] + TestClassBooleanProp() PropertyInterface[bool] + TestClassClassListProp() ListPropertyInterface[Ref[TestClass]] + TestClassClassProp() RefPropertyInterface[TestClass] + TestClassClassPropNoClass() RefPropertyInterface[TestClass] + TestClassDatetimeListProp() ListPropertyInterface[time.Time] + TestClassDatetimeScalarProp() PropertyInterface[time.Time] + TestClassDatetimestampScalarProp() PropertyInterface[time.Time] + TestClassEnumListProp() ListPropertyInterface[string] + TestClassEnumProp() PropertyInterface[string] + TestClassEnumPropNoClass() PropertyInterface[string] + TestClassFloatProp() PropertyInterface[float64] + TestClassIntegerProp() PropertyInterface[int] + NamedProperty() PropertyInterface[string] + TestClassNonShape() RefPropertyInterface[NonShapeClass] + TestClassNonnegativeIntegerProp() PropertyInterface[int] + TestClassPositiveIntegerProp() PropertyInterface[int] + TestClassRegex() PropertyInterface[string] + TestClassRegexDatetime() PropertyInterface[time.Time] + TestClassRegexDatetimestamp() PropertyInterface[time.Time] + TestClassRegexList() ListPropertyInterface[string] + TestClassStringListNoDatatype() ListPropertyInterface[string] + TestClassStringListProp() ListPropertyInterface[string] + TestClassStringScalarProp() PropertyInterface[string] +} + + +func MakeTestClass() TestClass { + return ConstructTestClassObject(&TestClassObject{}, testClassType) +} + +func MakeTestClassRef() Ref[TestClass] { + o := MakeTestClass() + return MakeObjectRef[TestClass](o) +} + +func (self *TestClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.ParentClassObject.Validate(path, handler) { + valid = false + } + { + prop_path := path.PushPath("encode") + if ! self.encode.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("import_") + if ! self.import_.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("testClassAnyuriProp") + if ! self.testClassAnyuriProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("testClassBooleanProp") + if ! self.testClassBooleanProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("testClassClassListProp") + if ! self.testClassClassListProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("testClassClassProp") + if ! self.testClassClassProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("testClassClassPropNoClass") + if ! self.testClassClassPropNoClass.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("testClassDatetimeListProp") + if ! self.testClassDatetimeListProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("testClassDatetimeScalarProp") + if ! self.testClassDatetimeScalarProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("testClassDatetimestampScalarProp") + if ! self.testClassDatetimestampScalarProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("testClassEnumListProp") + if ! self.testClassEnumListProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("testClassEnumProp") + if ! self.testClassEnumProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("testClassEnumPropNoClass") + if ! self.testClassEnumPropNoClass.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("testClassFloatProp") + if ! self.testClassFloatProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("testClassIntegerProp") + if ! self.testClassIntegerProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("namedProperty") + if ! self.namedProperty.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("testClassNonShape") + if ! self.testClassNonShape.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("testClassNonnegativeIntegerProp") + if ! self.testClassNonnegativeIntegerProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("testClassPositiveIntegerProp") + if ! self.testClassPositiveIntegerProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("testClassRegex") + if ! self.testClassRegex.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("testClassRegexDatetime") + if ! self.testClassRegexDatetime.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("testClassRegexDatetimestamp") + if ! self.testClassRegexDatetimestamp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("testClassRegexList") + if ! self.testClassRegexList.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("testClassStringListNoDatatype") + if ! self.testClassStringListNoDatatype.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("testClassStringListProp") + if ! self.testClassStringListProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("testClassStringScalarProp") + if ! self.testClassStringScalarProp.Check(prop_path, handler) { + valid = false + } + } + return valid +} + +func (self *TestClassObject) Walk(path Path, visit Visit) { + self.ParentClassObject.Walk(path, visit) + self.encode.Walk(path, visit) + self.import_.Walk(path, visit) + self.testClassAnyuriProp.Walk(path, visit) + self.testClassBooleanProp.Walk(path, visit) + self.testClassClassListProp.Walk(path, visit) + self.testClassClassProp.Walk(path, visit) + self.testClassClassPropNoClass.Walk(path, visit) + self.testClassDatetimeListProp.Walk(path, visit) + self.testClassDatetimeScalarProp.Walk(path, visit) + self.testClassDatetimestampScalarProp.Walk(path, visit) + self.testClassEnumListProp.Walk(path, visit) + self.testClassEnumProp.Walk(path, visit) + self.testClassEnumPropNoClass.Walk(path, visit) + self.testClassFloatProp.Walk(path, visit) + self.testClassIntegerProp.Walk(path, visit) + self.namedProperty.Walk(path, visit) + self.testClassNonShape.Walk(path, visit) + self.testClassNonnegativeIntegerProp.Walk(path, visit) + self.testClassPositiveIntegerProp.Walk(path, visit) + self.testClassRegex.Walk(path, visit) + self.testClassRegexDatetime.Walk(path, visit) + self.testClassRegexDatetimestamp.Walk(path, visit) + self.testClassRegexList.Walk(path, visit) + self.testClassStringListNoDatatype.Walk(path, visit) + self.testClassStringListProp.Walk(path, visit) + self.testClassStringScalarProp.Walk(path, visit) +} + + +func (self *TestClassObject) Encode() PropertyInterface[string] { return &self.encode } +func (self *TestClassObject) Import() PropertyInterface[string] { return &self.import_ } +func (self *TestClassObject) TestClassAnyuriProp() PropertyInterface[string] { return &self.testClassAnyuriProp } +func (self *TestClassObject) TestClassBooleanProp() PropertyInterface[bool] { return &self.testClassBooleanProp } +func (self *TestClassObject) TestClassClassListProp() ListPropertyInterface[Ref[TestClass]] { return &self.testClassClassListProp } +func (self *TestClassObject) TestClassClassProp() RefPropertyInterface[TestClass] { return &self.testClassClassProp } +func (self *TestClassObject) TestClassClassPropNoClass() RefPropertyInterface[TestClass] { return &self.testClassClassPropNoClass } +func (self *TestClassObject) TestClassDatetimeListProp() ListPropertyInterface[time.Time] { return &self.testClassDatetimeListProp } +func (self *TestClassObject) TestClassDatetimeScalarProp() PropertyInterface[time.Time] { return &self.testClassDatetimeScalarProp } +func (self *TestClassObject) TestClassDatetimestampScalarProp() PropertyInterface[time.Time] { return &self.testClassDatetimestampScalarProp } +func (self *TestClassObject) TestClassEnumListProp() ListPropertyInterface[string] { return &self.testClassEnumListProp } +func (self *TestClassObject) TestClassEnumProp() PropertyInterface[string] { return &self.testClassEnumProp } +func (self *TestClassObject) TestClassEnumPropNoClass() PropertyInterface[string] { return &self.testClassEnumPropNoClass } +func (self *TestClassObject) TestClassFloatProp() PropertyInterface[float64] { return &self.testClassFloatProp } +func (self *TestClassObject) TestClassIntegerProp() PropertyInterface[int] { return &self.testClassIntegerProp } +func (self *TestClassObject) NamedProperty() PropertyInterface[string] { return &self.namedProperty } +func (self *TestClassObject) TestClassNonShape() RefPropertyInterface[NonShapeClass] { return &self.testClassNonShape } +func (self *TestClassObject) TestClassNonnegativeIntegerProp() PropertyInterface[int] { return &self.testClassNonnegativeIntegerProp } +func (self *TestClassObject) TestClassPositiveIntegerProp() PropertyInterface[int] { return &self.testClassPositiveIntegerProp } +func (self *TestClassObject) TestClassRegex() PropertyInterface[string] { return &self.testClassRegex } +func (self *TestClassObject) TestClassRegexDatetime() PropertyInterface[time.Time] { return &self.testClassRegexDatetime } +func (self *TestClassObject) TestClassRegexDatetimestamp() PropertyInterface[time.Time] { return &self.testClassRegexDatetimestamp } +func (self *TestClassObject) TestClassRegexList() ListPropertyInterface[string] { return &self.testClassRegexList } +func (self *TestClassObject) TestClassStringListNoDatatype() ListPropertyInterface[string] { return &self.testClassStringListNoDatatype } +func (self *TestClassObject) TestClassStringListProp() ListPropertyInterface[string] { return &self.testClassStringListProp } +func (self *TestClassObject) TestClassStringScalarProp() PropertyInterface[string] { return &self.testClassStringScalarProp } + +func (self *TestClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.ParentClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + if self.encode.IsSet() { + val, err := EncodeString(self.encode.Get(), path.PushPath("encode"), testClassEncodeContext, state) + if err != nil { + return err + } + data["encode"] = val + } + if self.import_.IsSet() { + val, err := EncodeString(self.import_.Get(), path.PushPath("import_"), testClassImportContext, state) + if err != nil { + return err + } + data["import"] = val + } + if self.testClassAnyuriProp.IsSet() { + val, err := EncodeString(self.testClassAnyuriProp.Get(), path.PushPath("testClassAnyuriProp"), testClassTestClassAnyuriPropContext, state) + if err != nil { + return err + } + data["test-class/anyuri-prop"] = val + } + if self.testClassBooleanProp.IsSet() { + val, err := EncodeBoolean(self.testClassBooleanProp.Get(), path.PushPath("testClassBooleanProp"), testClassTestClassBooleanPropContext, state) + if err != nil { + return err + } + data["test-class/boolean-prop"] = val + } + if self.testClassClassListProp.IsSet() { + val, err := EncodeList[Ref[TestClass]](self.testClassClassListProp.Get(), path.PushPath("testClassClassListProp"), testClassTestClassClassListPropContext, state, EncodeRef[TestClass]) + if err != nil { + return err + } + data["test-class/class-list-prop"] = val + } + if self.testClassClassProp.IsSet() { + val, err := EncodeRef[TestClass](self.testClassClassProp.Get(), path.PushPath("testClassClassProp"), testClassTestClassClassPropContext, state) + if err != nil { + return err + } + data["test-class/class-prop"] = val + } + if self.testClassClassPropNoClass.IsSet() { + val, err := EncodeRef[TestClass](self.testClassClassPropNoClass.Get(), path.PushPath("testClassClassPropNoClass"), testClassTestClassClassPropNoClassContext, state) + if err != nil { + return err + } + data["test-class/class-prop-no-class"] = val + } + if self.testClassDatetimeListProp.IsSet() { + val, err := EncodeList[time.Time](self.testClassDatetimeListProp.Get(), path.PushPath("testClassDatetimeListProp"), testClassTestClassDatetimeListPropContext, state, EncodeDateTime) + if err != nil { + return err + } + data["test-class/datetime-list-prop"] = val + } + if self.testClassDatetimeScalarProp.IsSet() { + val, err := EncodeDateTime(self.testClassDatetimeScalarProp.Get(), path.PushPath("testClassDatetimeScalarProp"), testClassTestClassDatetimeScalarPropContext, state) + if err != nil { + return err + } + data["test-class/datetime-scalar-prop"] = val + } + if self.testClassDatetimestampScalarProp.IsSet() { + val, err := EncodeDateTime(self.testClassDatetimestampScalarProp.Get(), path.PushPath("testClassDatetimestampScalarProp"), testClassTestClassDatetimestampScalarPropContext, state) + if err != nil { + return err + } + data["test-class/datetimestamp-scalar-prop"] = val + } + if self.testClassEnumListProp.IsSet() { + val, err := EncodeList[string](self.testClassEnumListProp.Get(), path.PushPath("testClassEnumListProp"), testClassTestClassEnumListPropContext, state, EncodeIRI) + if err != nil { + return err + } + data["test-class/enum-list-prop"] = val + } + if self.testClassEnumProp.IsSet() { + val, err := EncodeIRI(self.testClassEnumProp.Get(), path.PushPath("testClassEnumProp"), testClassTestClassEnumPropContext, state) + if err != nil { + return err + } + data["test-class/enum-prop"] = val + } + if self.testClassEnumPropNoClass.IsSet() { + val, err := EncodeIRI(self.testClassEnumPropNoClass.Get(), path.PushPath("testClassEnumPropNoClass"), testClassTestClassEnumPropNoClassContext, state) + if err != nil { + return err + } + data["test-class/enum-prop-no-class"] = val + } + if self.testClassFloatProp.IsSet() { + val, err := EncodeFloat(self.testClassFloatProp.Get(), path.PushPath("testClassFloatProp"), testClassTestClassFloatPropContext, state) + if err != nil { + return err + } + data["test-class/float-prop"] = val + } + if self.testClassIntegerProp.IsSet() { + val, err := EncodeInteger(self.testClassIntegerProp.Get(), path.PushPath("testClassIntegerProp"), testClassTestClassIntegerPropContext, state) + if err != nil { + return err + } + data["test-class/integer-prop"] = val + } + if self.namedProperty.IsSet() { + val, err := EncodeString(self.namedProperty.Get(), path.PushPath("namedProperty"), testClassNamedPropertyContext, state) + if err != nil { + return err + } + data["test-class/named-property"] = val + } + if self.testClassNonShape.IsSet() { + val, err := EncodeRef[NonShapeClass](self.testClassNonShape.Get(), path.PushPath("testClassNonShape"), testClassTestClassNonShapeContext, state) + if err != nil { + return err + } + data["test-class/non-shape"] = val + } + if self.testClassNonnegativeIntegerProp.IsSet() { + val, err := EncodeInteger(self.testClassNonnegativeIntegerProp.Get(), path.PushPath("testClassNonnegativeIntegerProp"), testClassTestClassNonnegativeIntegerPropContext, state) + if err != nil { + return err + } + data["test-class/nonnegative-integer-prop"] = val + } + if self.testClassPositiveIntegerProp.IsSet() { + val, err := EncodeInteger(self.testClassPositiveIntegerProp.Get(), path.PushPath("testClassPositiveIntegerProp"), testClassTestClassPositiveIntegerPropContext, state) + if err != nil { + return err + } + data["test-class/positive-integer-prop"] = val + } + if self.testClassRegex.IsSet() { + val, err := EncodeString(self.testClassRegex.Get(), path.PushPath("testClassRegex"), testClassTestClassRegexContext, state) + if err != nil { + return err + } + data["test-class/regex"] = val + } + if self.testClassRegexDatetime.IsSet() { + val, err := EncodeDateTime(self.testClassRegexDatetime.Get(), path.PushPath("testClassRegexDatetime"), testClassTestClassRegexDatetimeContext, state) + if err != nil { + return err + } + data["test-class/regex-datetime"] = val + } + if self.testClassRegexDatetimestamp.IsSet() { + val, err := EncodeDateTime(self.testClassRegexDatetimestamp.Get(), path.PushPath("testClassRegexDatetimestamp"), testClassTestClassRegexDatetimestampContext, state) + if err != nil { + return err + } + data["test-class/regex-datetimestamp"] = val + } + if self.testClassRegexList.IsSet() { + val, err := EncodeList[string](self.testClassRegexList.Get(), path.PushPath("testClassRegexList"), testClassTestClassRegexListContext, state, EncodeString) + if err != nil { + return err + } + data["test-class/regex-list"] = val + } + if self.testClassStringListNoDatatype.IsSet() { + val, err := EncodeList[string](self.testClassStringListNoDatatype.Get(), path.PushPath("testClassStringListNoDatatype"), testClassTestClassStringListNoDatatypeContext, state, EncodeString) + if err != nil { + return err + } + data["test-class/string-list-no-datatype"] = val + } + if self.testClassStringListProp.IsSet() { + val, err := EncodeList[string](self.testClassStringListProp.Get(), path.PushPath("testClassStringListProp"), testClassTestClassStringListPropContext, state, EncodeString) + if err != nil { + return err + } + data["test-class/string-list-prop"] = val + } + if self.testClassStringScalarProp.IsSet() { + val, err := EncodeString(self.testClassStringScalarProp.Get(), path.PushPath("testClassStringScalarProp"), testClassTestClassStringScalarPropContext, state) + if err != nil { + return err + } + data["test-class/string-scalar-prop"] = val + } + return nil +} +type TestClassRequiredObject struct { + TestClassObject + + // A required string list property + testClassRequiredStringListProp ListProperty[string] + // A required scalar string property + testClassRequiredStringScalarProp Property[string] +} + + +type TestClassRequiredObjectType struct { + SHACLTypeBase +} +var testClassRequiredType TestClassRequiredObjectType +var testClassRequiredTestClassRequiredStringListPropContext = map[string]string{} +var testClassRequiredTestClassRequiredStringScalarPropContext = map[string]string{} + +func DecodeTestClassRequired (data any, path Path, context map[string]string) (Ref[TestClassRequired], error) { + return DecodeRef[TestClassRequired](data, path, context, testClassRequiredType) +} + +func (self TestClassRequiredObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(TestClassRequired) + _ = obj + switch name { + case "http://example.org/test-class/required-string-list-prop", "test-class/required-string-list-prop": + val, err := DecodeList[string](value, path, testClassRequiredTestClassRequiredStringListPropContext, DecodeString) + if err != nil { + return false, err + } + err = obj.TestClassRequiredStringListProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/required-string-scalar-prop", "test-class/required-string-scalar-prop": + val, err := DecodeString(value, path, testClassRequiredTestClassRequiredStringScalarPropContext) + if err != nil { + return false, err + } + err = obj.TestClassRequiredStringScalarProp().Set(val) + if err != nil { + return false, err + } + return true, nil + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self TestClassRequiredObjectType) Create() SHACLObject { + return ConstructTestClassRequiredObject(&TestClassRequiredObject{}, self) +} + +func ConstructTestClassRequiredObject(o *TestClassRequiredObject, typ SHACLType) *TestClassRequiredObject { + ConstructTestClassObject(&o.TestClassObject, typ) + { + validators := []Validator[string]{} + o.testClassRequiredStringListProp = NewListProperty[string]("testClassRequiredStringListProp", validators) + } + { + validators := []Validator[string]{} + o.testClassRequiredStringScalarProp = NewProperty[string]("testClassRequiredStringScalarProp", validators) + } + return o +} + +type TestClassRequired interface { + TestClass + TestClassRequiredStringListProp() ListPropertyInterface[string] + TestClassRequiredStringScalarProp() PropertyInterface[string] +} + + +func MakeTestClassRequired() TestClassRequired { + return ConstructTestClassRequiredObject(&TestClassRequiredObject{}, testClassRequiredType) +} + +func MakeTestClassRequiredRef() Ref[TestClassRequired] { + o := MakeTestClassRequired() + return MakeObjectRef[TestClassRequired](o) +} + +func (self *TestClassRequiredObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.TestClassObject.Validate(path, handler) { + valid = false + } + { + prop_path := path.PushPath("testClassRequiredStringListProp") + if ! self.testClassRequiredStringListProp.Check(prop_path, handler) { + valid = false + } + if len(self.testClassRequiredStringListProp.Get()) < 1 { + if handler != nil { + handler.HandleError(&ValidationError{ + "testClassRequiredStringListProp", + "Too few elements. Minimum of 1 required"}, + prop_path) + } + valid = false + } + if len(self.testClassRequiredStringListProp.Get()) > 2 { + if handler != nil { + handler.HandleError(&ValidationError{ + "testClassRequiredStringListProp", + "Too many elements. Maximum of 2 allowed"}, + prop_path) + } + valid = false + } + } + { + prop_path := path.PushPath("testClassRequiredStringScalarProp") + if ! self.testClassRequiredStringScalarProp.Check(prop_path, handler) { + valid = false + } + if ! self.testClassRequiredStringScalarProp.IsSet() { + if handler != nil { + handler.HandleError(&ValidationError{"testClassRequiredStringScalarProp", "Value is required"}, prop_path) + } + valid = false + } + } + return valid +} + +func (self *TestClassRequiredObject) Walk(path Path, visit Visit) { + self.TestClassObject.Walk(path, visit) + self.testClassRequiredStringListProp.Walk(path, visit) + self.testClassRequiredStringScalarProp.Walk(path, visit) +} + + +func (self *TestClassRequiredObject) TestClassRequiredStringListProp() ListPropertyInterface[string] { return &self.testClassRequiredStringListProp } +func (self *TestClassRequiredObject) TestClassRequiredStringScalarProp() PropertyInterface[string] { return &self.testClassRequiredStringScalarProp } + +func (self *TestClassRequiredObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.TestClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + if self.testClassRequiredStringListProp.IsSet() { + val, err := EncodeList[string](self.testClassRequiredStringListProp.Get(), path.PushPath("testClassRequiredStringListProp"), testClassRequiredTestClassRequiredStringListPropContext, state, EncodeString) + if err != nil { + return err + } + data["test-class/required-string-list-prop"] = val + } + if self.testClassRequiredStringScalarProp.IsSet() { + val, err := EncodeString(self.testClassRequiredStringScalarProp.Get(), path.PushPath("testClassRequiredStringScalarProp"), testClassRequiredTestClassRequiredStringScalarPropContext, state) + if err != nil { + return err + } + data["test-class/required-string-scalar-prop"] = val + } + return nil +} + +// A class derived from test-class +type TestDerivedClassObject struct { + TestClassObject + + // A string property in a derived class + testDerivedClassStringProp Property[string] +} + + +type TestDerivedClassObjectType struct { + SHACLTypeBase +} +var testDerivedClassType TestDerivedClassObjectType +var testDerivedClassTestDerivedClassStringPropContext = map[string]string{} + +func DecodeTestDerivedClass (data any, path Path, context map[string]string) (Ref[TestDerivedClass], error) { + return DecodeRef[TestDerivedClass](data, path, context, testDerivedClassType) +} + +func (self TestDerivedClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(TestDerivedClass) + _ = obj + switch name { + case "http://example.org/test-derived-class/string-prop", "test-derived-class/string-prop": + val, err := DecodeString(value, path, testDerivedClassTestDerivedClassStringPropContext) + if err != nil { + return false, err + } + err = obj.TestDerivedClassStringProp().Set(val) + if err != nil { + return false, err + } + return true, nil + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self TestDerivedClassObjectType) Create() SHACLObject { + return ConstructTestDerivedClassObject(&TestDerivedClassObject{}, self) +} + +func ConstructTestDerivedClassObject(o *TestDerivedClassObject, typ SHACLType) *TestDerivedClassObject { + ConstructTestClassObject(&o.TestClassObject, typ) + { + validators := []Validator[string]{} + o.testDerivedClassStringProp = NewProperty[string]("testDerivedClassStringProp", validators) + } + return o +} + +type TestDerivedClass interface { + TestClass + TestDerivedClassStringProp() PropertyInterface[string] +} + + +func MakeTestDerivedClass() TestDerivedClass { + return ConstructTestDerivedClassObject(&TestDerivedClassObject{}, testDerivedClassType) +} + +func MakeTestDerivedClassRef() Ref[TestDerivedClass] { + o := MakeTestDerivedClass() + return MakeObjectRef[TestDerivedClass](o) +} + +func (self *TestDerivedClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.TestClassObject.Validate(path, handler) { + valid = false + } + { + prop_path := path.PushPath("testDerivedClassStringProp") + if ! self.testDerivedClassStringProp.Check(prop_path, handler) { + valid = false + } + } + return valid +} + +func (self *TestDerivedClassObject) Walk(path Path, visit Visit) { + self.TestClassObject.Walk(path, visit) + self.testDerivedClassStringProp.Walk(path, visit) +} + + +func (self *TestDerivedClassObject) TestDerivedClassStringProp() PropertyInterface[string] { return &self.testDerivedClassStringProp } + +func (self *TestDerivedClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.TestClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + if self.testDerivedClassStringProp.IsSet() { + val, err := EncodeString(self.testDerivedClassStringProp.Get(), path.PushPath("testDerivedClassStringProp"), testDerivedClassTestDerivedClassStringPropContext, state) + if err != nil { + return err + } + data["test-derived-class/string-prop"] = val + } + return nil +} + +// A class that uses an abstract extensible class +type UsesExtensibleAbstractClassObject struct { + SHACLObjectBase + + // A property that references and abstract extensible class + usesExtensibleAbstractClassProp RefProperty[ExtensibleAbstractClass] +} + + +type UsesExtensibleAbstractClassObjectType struct { + SHACLTypeBase +} +var usesExtensibleAbstractClassType UsesExtensibleAbstractClassObjectType +var usesExtensibleAbstractClassUsesExtensibleAbstractClassPropContext = map[string]string{} + +func DecodeUsesExtensibleAbstractClass (data any, path Path, context map[string]string) (Ref[UsesExtensibleAbstractClass], error) { + return DecodeRef[UsesExtensibleAbstractClass](data, path, context, usesExtensibleAbstractClassType) +} + +func (self UsesExtensibleAbstractClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(UsesExtensibleAbstractClass) + _ = obj + switch name { + case "http://example.org/uses-extensible-abstract-class/prop", "uses-extensible-abstract-class/prop": + val, err := DecodeExtensibleAbstractClass(value, path, usesExtensibleAbstractClassUsesExtensibleAbstractClassPropContext) + if err != nil { + return false, err + } + err = obj.UsesExtensibleAbstractClassProp().Set(val) + if err != nil { + return false, err + } + return true, nil + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self UsesExtensibleAbstractClassObjectType) Create() SHACLObject { + return ConstructUsesExtensibleAbstractClassObject(&UsesExtensibleAbstractClassObject{}, self) +} + +func ConstructUsesExtensibleAbstractClassObject(o *UsesExtensibleAbstractClassObject, typ SHACLType) *UsesExtensibleAbstractClassObject { + ConstructSHACLObjectBase(&o.SHACLObjectBase, typ) + { + validators := []Validator[Ref[ExtensibleAbstractClass]]{} + o.usesExtensibleAbstractClassProp = NewRefProperty[ExtensibleAbstractClass]("usesExtensibleAbstractClassProp", validators) + } + return o +} + +type UsesExtensibleAbstractClass interface { + SHACLObject + UsesExtensibleAbstractClassProp() RefPropertyInterface[ExtensibleAbstractClass] +} + + +func MakeUsesExtensibleAbstractClass() UsesExtensibleAbstractClass { + return ConstructUsesExtensibleAbstractClassObject(&UsesExtensibleAbstractClassObject{}, usesExtensibleAbstractClassType) +} + +func MakeUsesExtensibleAbstractClassRef() Ref[UsesExtensibleAbstractClass] { + o := MakeUsesExtensibleAbstractClass() + return MakeObjectRef[UsesExtensibleAbstractClass](o) +} + +func (self *UsesExtensibleAbstractClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.SHACLObjectBase.Validate(path, handler) { + valid = false + } + { + prop_path := path.PushPath("usesExtensibleAbstractClassProp") + if ! self.usesExtensibleAbstractClassProp.Check(prop_path, handler) { + valid = false + } + if ! self.usesExtensibleAbstractClassProp.IsSet() { + if handler != nil { + handler.HandleError(&ValidationError{"usesExtensibleAbstractClassProp", "Value is required"}, prop_path) + } + valid = false + } + } + return valid +} + +func (self *UsesExtensibleAbstractClassObject) Walk(path Path, visit Visit) { + self.SHACLObjectBase.Walk(path, visit) + self.usesExtensibleAbstractClassProp.Walk(path, visit) +} + + +func (self *UsesExtensibleAbstractClassObject) UsesExtensibleAbstractClassProp() RefPropertyInterface[ExtensibleAbstractClass] { return &self.usesExtensibleAbstractClassProp } + +func (self *UsesExtensibleAbstractClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.SHACLObjectBase.EncodeProperties(data, path, state); err != nil { + return err + } + if self.usesExtensibleAbstractClassProp.IsSet() { + val, err := EncodeRef[ExtensibleAbstractClass](self.usesExtensibleAbstractClassProp.Get(), path.PushPath("usesExtensibleAbstractClassProp"), usesExtensibleAbstractClassUsesExtensibleAbstractClassPropContext, state) + if err != nil { + return err + } + data["uses-extensible-abstract-class/prop"] = val + } + return nil +} + +// Derived class that sorts before the parent to test ordering +type AaaDerivedClassObject struct { + ParentClassObject + +} + + +type AaaDerivedClassObjectType struct { + SHACLTypeBase +} +var aaaDerivedClassType AaaDerivedClassObjectType + +func DecodeAaaDerivedClass (data any, path Path, context map[string]string) (Ref[AaaDerivedClass], error) { + return DecodeRef[AaaDerivedClass](data, path, context, aaaDerivedClassType) +} + +func (self AaaDerivedClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(AaaDerivedClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self AaaDerivedClassObjectType) Create() SHACLObject { + return ConstructAaaDerivedClassObject(&AaaDerivedClassObject{}, self) +} + +func ConstructAaaDerivedClassObject(o *AaaDerivedClassObject, typ SHACLType) *AaaDerivedClassObject { + ConstructParentClassObject(&o.ParentClassObject, typ) + return o +} + +type AaaDerivedClass interface { + ParentClass +} + + +func MakeAaaDerivedClass() AaaDerivedClass { + return ConstructAaaDerivedClassObject(&AaaDerivedClassObject{}, aaaDerivedClassType) +} + +func MakeAaaDerivedClassRef() Ref[AaaDerivedClass] { + o := MakeAaaDerivedClass() + return MakeObjectRef[AaaDerivedClass](o) +} + +func (self *AaaDerivedClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.ParentClassObject.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *AaaDerivedClassObject) Walk(path Path, visit Visit) { + self.ParentClassObject.Walk(path, visit) +} + + + +func (self *AaaDerivedClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.ParentClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// A class that derives its nodeKind from parent +type DerivedNodeKindIriObject struct { + NodeKindIriObject + +} + + +type DerivedNodeKindIriObjectType struct { + SHACLTypeBase +} +var derivedNodeKindIriType DerivedNodeKindIriObjectType + +func DecodeDerivedNodeKindIri (data any, path Path, context map[string]string) (Ref[DerivedNodeKindIri], error) { + return DecodeRef[DerivedNodeKindIri](data, path, context, derivedNodeKindIriType) +} + +func (self DerivedNodeKindIriObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(DerivedNodeKindIri) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self DerivedNodeKindIriObjectType) Create() SHACLObject { + return ConstructDerivedNodeKindIriObject(&DerivedNodeKindIriObject{}, self) +} + +func ConstructDerivedNodeKindIriObject(o *DerivedNodeKindIriObject, typ SHACLType) *DerivedNodeKindIriObject { + ConstructNodeKindIriObject(&o.NodeKindIriObject, typ) + return o +} + +type DerivedNodeKindIri interface { + NodeKindIri +} + + +func MakeDerivedNodeKindIri() DerivedNodeKindIri { + return ConstructDerivedNodeKindIriObject(&DerivedNodeKindIriObject{}, derivedNodeKindIriType) +} + +func MakeDerivedNodeKindIriRef() Ref[DerivedNodeKindIri] { + o := MakeDerivedNodeKindIri() + return MakeObjectRef[DerivedNodeKindIri](o) +} + +func (self *DerivedNodeKindIriObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.NodeKindIriObject.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *DerivedNodeKindIriObject) Walk(path Path, visit Visit) { + self.NodeKindIriObject.Walk(path, visit) +} + + + +func (self *DerivedNodeKindIriObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.NodeKindIriObject.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// An extensible class +type ExtensibleClassObject struct { + LinkClassObject + SHACLExtensibleBase + + // An extensible property + extensibleClassProperty Property[string] + // A required extensible property + extensibleClassRequired Property[string] +} + + +type ExtensibleClassObjectType struct { + SHACLTypeBase +} +var extensibleClassType ExtensibleClassObjectType +var extensibleClassExtensibleClassPropertyContext = map[string]string{} +var extensibleClassExtensibleClassRequiredContext = map[string]string{} + +func DecodeExtensibleClass (data any, path Path, context map[string]string) (Ref[ExtensibleClass], error) { + return DecodeRef[ExtensibleClass](data, path, context, extensibleClassType) +} + +func (self ExtensibleClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(ExtensibleClass) + _ = obj + switch name { + case "http://example.org/extensible-class/property", "extensible-class/property": + val, err := DecodeString(value, path, extensibleClassExtensibleClassPropertyContext) + if err != nil { + return false, err + } + err = obj.ExtensibleClassProperty().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/extensible-class/required", "extensible-class/required": + val, err := DecodeString(value, path, extensibleClassExtensibleClassRequiredContext) + if err != nil { + return false, err + } + err = obj.ExtensibleClassRequired().Set(val) + if err != nil { + return false, err + } + return true, nil + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self ExtensibleClassObjectType) Create() SHACLObject { + return ConstructExtensibleClassObject(&ExtensibleClassObject{}, self) +} + +func ConstructExtensibleClassObject(o *ExtensibleClassObject, typ SHACLType) *ExtensibleClassObject { + ConstructLinkClassObject(&o.LinkClassObject, typ) + { + validators := []Validator[string]{} + o.extensibleClassProperty = NewProperty[string]("extensibleClassProperty", validators) + } + { + validators := []Validator[string]{} + o.extensibleClassRequired = NewProperty[string]("extensibleClassRequired", validators) + } + return o +} + +type ExtensibleClass interface { + LinkClass + ExtensibleClassProperty() PropertyInterface[string] + ExtensibleClassRequired() PropertyInterface[string] +} + + +func MakeExtensibleClass() ExtensibleClass { + return ConstructExtensibleClassObject(&ExtensibleClassObject{}, extensibleClassType) +} + +func MakeExtensibleClassRef() Ref[ExtensibleClass] { + o := MakeExtensibleClass() + return MakeObjectRef[ExtensibleClass](o) +} + +func (self *ExtensibleClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.LinkClassObject.Validate(path, handler) { + valid = false + } + { + prop_path := path.PushPath("extensibleClassProperty") + if ! self.extensibleClassProperty.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("extensibleClassRequired") + if ! self.extensibleClassRequired.Check(prop_path, handler) { + valid = false + } + if ! self.extensibleClassRequired.IsSet() { + if handler != nil { + handler.HandleError(&ValidationError{"extensibleClassRequired", "Value is required"}, prop_path) + } + valid = false + } + } + return valid +} + +func (self *ExtensibleClassObject) Walk(path Path, visit Visit) { + self.LinkClassObject.Walk(path, visit) + self.extensibleClassProperty.Walk(path, visit) + self.extensibleClassRequired.Walk(path, visit) +} + + +func (self *ExtensibleClassObject) ExtensibleClassProperty() PropertyInterface[string] { return &self.extensibleClassProperty } +func (self *ExtensibleClassObject) ExtensibleClassRequired() PropertyInterface[string] { return &self.extensibleClassRequired } + +func (self *ExtensibleClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.LinkClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + if self.extensibleClassProperty.IsSet() { + val, err := EncodeString(self.extensibleClassProperty.Get(), path.PushPath("extensibleClassProperty"), extensibleClassExtensibleClassPropertyContext, state) + if err != nil { + return err + } + data["extensible-class/property"] = val + } + if self.extensibleClassRequired.IsSet() { + val, err := EncodeString(self.extensibleClassRequired.Get(), path.PushPath("extensibleClassRequired"), extensibleClassExtensibleClassRequiredContext, state) + if err != nil { + return err + } + data["extensible-class/required"] = val + } + self.SHACLExtensibleBase.EncodeExtProperties(data, path) + return nil +} + + +func init() { + objectTypes = make(map[string] SHACLType) + abstractClassType = AbstractClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/abstract-class", + compactTypeIRI: NewOptional[string]("abstract-class"), + isAbstract: true, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + }, + }, + } + RegisterType(abstractClassType) + abstractShClassType = AbstractShClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/abstract-sh-class", + compactTypeIRI: NewOptional[string]("abstract-sh-class"), + isAbstract: true, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + }, + }, + } + RegisterType(abstractShClassType) + abstractSpdxClassType = AbstractSpdxClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/abstract-spdx-class", + compactTypeIRI: NewOptional[string]("abstract-spdx-class"), + isAbstract: true, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + }, + }, + } + RegisterType(abstractSpdxClassType) + concreteClassType = ConcreteClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/concrete-class", + compactTypeIRI: NewOptional[string]("concrete-class"), + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + "http://example.org/abstract-class", + }, + }, + } + RegisterType(concreteClassType) + concreteShClassType = ConcreteShClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/concrete-sh-class", + compactTypeIRI: NewOptional[string]("concrete-sh-class"), + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + "http://example.org/abstract-sh-class", + }, + }, + } + RegisterType(concreteShClassType) + concreteSpdxClassType = ConcreteSpdxClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/concrete-spdx-class", + compactTypeIRI: NewOptional[string]("concrete-spdx-class"), + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + "http://example.org/abstract-spdx-class", + }, + }, + } + RegisterType(concreteSpdxClassType) + enumTypeType = EnumTypeObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/enumType", + compactTypeIRI: NewOptional[string]("enumType"), + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + }, + }, + } + RegisterType(enumTypeType) + extensibleAbstractClassType = ExtensibleAbstractClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/extensible-abstract-class", + compactTypeIRI: NewOptional[string]("extensible-abstract-class"), + isAbstract: true, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + isExtensible: NewOptional[bool](true), + parentIRIs: []string{ + }, + }, + } + RegisterType(extensibleAbstractClassType) + idPropClassType = IdPropClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/id-prop-class", + compactTypeIRI: NewOptional[string]("id-prop-class"), + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + idAlias: NewOptional[string]("testid"), + parentIRIs: []string{ + }, + }, + } + RegisterType(idPropClassType) + inheritedIdPropClassType = InheritedIdPropClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/inherited-id-prop-class", + compactTypeIRI: NewOptional[string]("inherited-id-prop-class"), + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + idAlias: NewOptional[string]("testid"), + parentIRIs: []string{ + "http://example.org/id-prop-class", + }, + }, + } + RegisterType(inheritedIdPropClassType) + linkClassType = LinkClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/link-class", + compactTypeIRI: NewOptional[string]("link-class"), + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + }, + }, + } + RegisterType(linkClassType) + linkDerivedClassType = LinkDerivedClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/link-derived-class", + compactTypeIRI: NewOptional[string]("link-derived-class"), + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + "http://example.org/link-class", + }, + }, + } + RegisterType(linkDerivedClassType) + nodeKindBlankType = NodeKindBlankObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/node-kind-blank", + compactTypeIRI: NewOptional[string]("node-kind-blank"), + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNode), + parentIRIs: []string{ + "http://example.org/link-class", + }, + }, + } + RegisterType(nodeKindBlankType) + nodeKindIriType = NodeKindIriObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/node-kind-iri", + compactTypeIRI: NewOptional[string]("node-kind-iri"), + isAbstract: false, + nodeKind: NewOptional[int](NodeKindIRI), + parentIRIs: []string{ + "http://example.org/link-class", + }, + }, + } + RegisterType(nodeKindIriType) + nodeKindIriOrBlankType = NodeKindIriOrBlankObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/node-kind-iri-or-blank", + compactTypeIRI: NewOptional[string]("node-kind-iri-or-blank"), + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + "http://example.org/link-class", + }, + }, + } + RegisterType(nodeKindIriOrBlankType) + nonShapeClassType = NonShapeClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/non-shape-class", + compactTypeIRI: NewOptional[string]("non-shape-class"), + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + }, + }, + } + RegisterType(nonShapeClassType) + parentClassType = ParentClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/parent-class", + compactTypeIRI: NewOptional[string]("parent-class"), + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + }, + }, + } + RegisterType(parentClassType) + requiredAbstractType = RequiredAbstractObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/required-abstract", + compactTypeIRI: NewOptional[string]("required-abstract"), + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + }, + }, + } + RegisterType(requiredAbstractType) + testAnotherClassType = TestAnotherClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/test-another-class", + compactTypeIRI: NewOptional[string]("test-another-class"), + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + }, + }, + } + RegisterType(testAnotherClassType) + testClassType = TestClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/test-class", + compactTypeIRI: NewOptional[string]("test-class"), + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + "http://example.org/parent-class", + }, + }, + } + RegisterType(testClassType) + testClassRequiredType = TestClassRequiredObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/test-class-required", + compactTypeIRI: NewOptional[string]("test-class-required"), + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + "http://example.org/test-class", + }, + }, + } + RegisterType(testClassRequiredType) + testDerivedClassType = TestDerivedClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/test-derived-class", + compactTypeIRI: NewOptional[string]("test-derived-class"), + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + "http://example.org/test-class", + }, + }, + } + RegisterType(testDerivedClassType) + usesExtensibleAbstractClassType = UsesExtensibleAbstractClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/uses-extensible-abstract-class", + compactTypeIRI: NewOptional[string]("uses-extensible-abstract-class"), + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + }, + }, + } + RegisterType(usesExtensibleAbstractClassType) + aaaDerivedClassType = AaaDerivedClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/aaa-derived-class", + compactTypeIRI: NewOptional[string]("aaa-derived-class"), + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + "http://example.org/parent-class", + }, + }, + } + RegisterType(aaaDerivedClassType) + derivedNodeKindIriType = DerivedNodeKindIriObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/derived-node-kind-iri", + compactTypeIRI: NewOptional[string]("derived-node-kind-iri"), + isAbstract: false, + nodeKind: NewOptional[int](NodeKindIRI), + parentIRIs: []string{ + "http://example.org/node-kind-iri", + }, + }, + } + RegisterType(derivedNodeKindIriType) + extensibleClassType = ExtensibleClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/extensible-class", + compactTypeIRI: NewOptional[string]("extensible-class"), + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + isExtensible: NewOptional[bool](true), + parentIRIs: []string{ + "http://example.org/link-class", + }, + }, + } + RegisterType(extensibleClassType) +} diff --git a/tests/expect/golang/nocontext/test.go b/tests/expect/golang/nocontext/test.go new file mode 100644 index 0000000..def56b1 --- /dev/null +++ b/tests/expect/golang/nocontext/test.go @@ -0,0 +1,4900 @@ +// +// +// + +package model + +import ( + "encoding/json" + "fmt" + "reflect" + "regexp" + "sort" + "strconv" + "strings" + "time" + + "github.com/ncruces/go-strftime" +) + +// Validation Error +type ValidationError struct { + Property string + Err string +} + +func (e *ValidationError) Error() string { return e.Property + ": " + e.Err } + +// Conversion Error +type ConversionError struct { + From string + To string +} + +func (e *ConversionError) Error() string { + return "Unable to convert from " + e.From + " to " + e.To +} + +// Decode Error +type DecodeError struct { + Path Path + Err string +} + +func (e *DecodeError) Error() string { + return e.Path.ToString() + ": " + e.Err +} + +type EncodeError struct { + Path Path + Err string +} + +func (e *EncodeError) Error() string { + return e.Path.ToString() + ": " + e.Err +} + +// Path +type Path struct { + Path []string +} + +func (p *Path) PushPath(s string) Path { + new_p := *p + new_p.Path = append(new_p.Path, s) + return new_p +} + +func (p *Path) PushIndex(idx int) Path { + return p.PushPath("[" + strconv.Itoa(idx) + "]") +} + +func (p *Path) ToString() string { + return "." + strings.Join(p.Path, ".") +} + +// Error Handler +type ErrorHandler interface { + HandleError(error, Path) +} + +// Reference +type Ref[T SHACLObject] interface { + GetIRI() string + GetObj() T + IsSet() bool + IsObj() bool + IsIRI() bool +} + +type ref[T SHACLObject] struct { + obj *T + iri string +} + +func (r ref[T]) GetIRI() string { + if r.iri != "" { + return r.iri + } + if r.obj != nil { + o := *r.obj + if o.ID().IsSet() { + return o.ID().Get() + } + } + return "" +} + +func (r ref[T]) GetObj() T { + return *r.obj +} + +func (r ref[T]) IsSet() bool { return r.IsIRI() || r.IsObj() } +func (r ref[T]) IsObj() bool { return r.obj != nil } +func (r ref[T]) IsIRI() bool { return r.iri != "" } + +func MakeObjectRef[T SHACLObject](obj T) Ref[T] { + return ref[T]{&obj, ""} +} + +func MakeIRIRef[T SHACLObject](iri string) Ref[T] { + return ref[T]{nil, iri} +} + +// Convert one reference to another. Note that the output type is first so it +// can be specified, while the input type is generally inferred from the argument +func ConvertRef[TO SHACLObject, FROM SHACLObject](in Ref[FROM]) (Ref[TO], error) { + if in.IsObj() { + out_obj, ok := any(in.GetObj()).(TO) + if !ok { + return nil, &ConversionError{reflect.TypeOf(ref[FROM]{}).Name(), reflect.TypeOf(ref[TO]{}).Name()} + } + return ref[TO]{&out_obj, in.GetIRI()}, nil + } + return ref[TO]{nil, in.GetIRI()}, nil +} + +type Visit func(Path, any) + +// Base SHACL Object +type SHACLObjectBase struct { + // Object ID + id Property[string] + typ SHACLType + typeIRI string +} + +func (self *SHACLObjectBase) ID() PropertyInterface[string] { return &self.id } + +func (self *SHACLObjectBase) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + + switch self.typ.GetNodeKind() { + case NodeKindBlankNode: + if self.ID().IsSet() && ! IsBlankNode(self.ID().Get()) { + handler.HandleError(&ValidationError{ + "id", + "ID must by be blank node"}, + path.PushPath("id")) + valid = false + } + case NodeKindIRI: + if ! self.ID().IsSet() || ! IsIRI(self.ID().Get()) { + handler.HandleError(&ValidationError{ + "id", + "ID must be an IRI"}, + path.PushPath("id")) + valid = false + } + case NodeKindBlankNodeOrIRI: + if self.ID().IsSet() && ! IsBlankNode(self.ID().Get()) && ! IsIRI(self.ID().Get()) { + handler.HandleError(&ValidationError{ + "id", + "ID must be a blank node or IRI"}, + path.PushPath("id")) + valid = false + } + default: + panic("Unknown node kind") + } + + return valid +} + +func (self *SHACLObjectBase) Walk(path Path, visit Visit) { + self.id.Walk(path, visit) +} + +func (self *SHACLObjectBase) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if self.typeIRI != "" { + data["@type"] = self.typeIRI + } else { + data["@type"] = self.typ.GetCompactTypeIRI().GetDefault(self.typ.GetTypeIRI()) + } + + id_prop := self.typ.GetIDAlias().GetDefault("@id") + + if self.id.IsSet() { + val, err := EncodeIRI(self.id.Get(), path.PushPath(id_prop), map[string]string{}, state) + if err != nil { + return err + } + data[id_prop] = val + } + + return nil +} + +func (self *SHACLObjectBase) GetType() SHACLType { + return self.typ +} + +func (self *SHACLObjectBase) setTypeIRI(iri string) { + self.typeIRI = iri +} + +func ConstructSHACLObjectBase(o *SHACLObjectBase, typ SHACLType) *SHACLObjectBase { + o.id = NewProperty[string]("id", []Validator[string]{ IDValidator{}, }) + o.typ = typ + return o +} + +type SHACLObject interface { + ID() PropertyInterface[string] + Validate(path Path, handler ErrorHandler) bool + Walk(path Path, visit Visit) + EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error + GetType() SHACLType + setTypeIRI(iri string) +} + +func EncodeSHACLObject(o SHACLObject, path Path, state *EncodeState) (any, error) { + if state != nil { + if state.Written[o] { + if o.ID().IsSet() { + return o.ID().Get(), nil + } + + return nil, &EncodeError{ + path, + "Object referenced multiple times, but does not have an ID assigned", + } + } + + state.Written[o] = true + } + + d := make(map[string]interface{}) + return d, o.EncodeProperties(d, path, state) +} + +// Extensible Object + +type SHACLExtensibleBase struct { + properties map[string][]any +} + +func (self *SHACLExtensibleBase) GetExtProperty(name string) []any { + return self.properties[name] +} + +func (self *SHACLExtensibleBase) SetExtProperty(name string, value []any) { + if self.properties == nil { + self.properties = make(map[string][]any) + } + self.properties[name] = value +} + +func (self *SHACLExtensibleBase) DeleteExtProperty(name string) { + delete(self.properties, name) +} + +func (self *SHACLExtensibleBase) EncodeExtProperties(data map[string]any, path Path) error { + for k, values := range self.properties { + if len(values) == 0 { + continue + } + + lst := []any{} + for _, v := range values { + lst = append(lst, v) + } + data[k] = lst + } + return nil +} + +type SHACLExtensibleObject interface { + GetExtProperty(string) []any + SetExtProperty(string, []any) + DeleteExtProperty(string) +} + +// Type Metadata +const NodeKindBlankNode = 0 +const NodeKindIRI = 1 +const NodeKindBlankNodeOrIRI = 2 + +type SHACLType interface { + GetTypeIRI() string + GetCompactTypeIRI() Optional[string] + GetNodeKind() int + GetIDAlias() Optional[string] + DecodeProperty(SHACLObject, string, interface{}, Path) (bool, error) + Create() SHACLObject + IsAbstract() bool + IsExtensible() bool + IsSubClassOf(SHACLType) bool +} + +type SHACLTypeBase struct { + typeIRI string + compactTypeIRI Optional[string] + idAlias Optional[string] + isExtensible Optional[bool] + isAbstract bool + parentIRIs []string + nodeKind Optional[int] +} + +func (self SHACLTypeBase) GetTypeIRI() string { + return self.typeIRI +} + +func (self SHACLTypeBase) GetCompactTypeIRI() Optional[string] { + return self.compactTypeIRI +} + +func (self SHACLTypeBase) GetNodeKind() int { + if self.nodeKind.IsSet() { + return self.nodeKind.Get() + } + + for _, parent_id := range(self.parentIRIs) { + p := objectTypes[parent_id] + return p.GetNodeKind() + } + + return NodeKindBlankNodeOrIRI +} + +func (self SHACLTypeBase) GetIDAlias() Optional[string] { + if self.idAlias.IsSet() { + return self.idAlias + } + + for _, parent_id := range(self.parentIRIs) { + p := objectTypes[parent_id] + a := p.GetIDAlias() + if a.IsSet() { + return a + } + } + + return self.idAlias +} + +func (self SHACLTypeBase) IsAbstract() bool { + return self.isAbstract +} + +func (self SHACLTypeBase) IsExtensible() bool { + if self.isExtensible.IsSet() { + return self.isExtensible.Get() + } + + for _, parent_id := range(self.parentIRIs) { + p := objectTypes[parent_id] + if p.IsExtensible() { + return true + } + } + + return false +} + +func (self SHACLTypeBase) IsSubClassOf(other SHACLType) bool { + if other.GetTypeIRI() == self.typeIRI { + return true + } + + for _, parent_id := range(self.parentIRIs) { + p := objectTypes[parent_id] + if p.IsSubClassOf(other) { + return true + } + } + + return false +} + +type EncodeState struct { + Written map[SHACLObject]bool +} + +func (self SHACLTypeBase) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + id_alias := self.GetIDAlias() + if id_alias.IsSet() { + switch name { + case id_alias.Get(): + val, err := DecodeString(value, path.PushPath(name), map[string]string{}) + if err != nil { + return false, err + } + err = o.ID().Set(val) + if err != nil { + return false, err + } + return true, nil + case "@id": + return true, &DecodeError{ + path.PushPath(name), + "'@id' is not allowed for " + self.GetTypeIRI() + " which has an ID alias", + } + } + } else if name == "@id" { + val, err := DecodeString(value, path.PushPath(name), map[string]string{}) + if err != nil { + return false, err + } + err = o.ID().Set(val) + if err != nil { + return false, err + } + return true, nil + } + + for _, parent_id := range(self.parentIRIs) { + p := objectTypes[parent_id] + found, err := p.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + if self.isExtensible.GetDefault(false) { + obj := o.(SHACLExtensibleObject) + v, err := DecodeAny(value, path, map[string]string{}) + if err != nil { + return false, err + } + + lst, is_list := v.([]interface{}) + if is_list { + obj.SetExtProperty(name, lst) + } else { + obj.SetExtProperty(name, []interface{}{v}) + } + return true, nil + } + return false, nil +} + + +var objectTypes map[string] SHACLType + +func RegisterType(typ SHACLType) { + objectTypes[typ.GetTypeIRI()] = typ + compact := typ.GetCompactTypeIRI() + if compact.IsSet() { + objectTypes[compact.Get()] = typ + } +} + +// SHACLObjectSet +type SHACLObjectSet interface { + AddObject(r SHACLObject) + Decode(decoder *json.Decoder) error + Encode(encoder *json.Encoder) error + Walk(visit Visit) + Validate(handler ErrorHandler) bool +} + +type SHACLObjectSetObject struct { + objects []SHACLObject +} + +func (self *SHACLObjectSetObject) AddObject(r SHACLObject) { + self.objects = append(self.objects, r) +} + +func (self *SHACLObjectSetObject) Decode(decoder *json.Decoder) error { + path := Path{} + + var data map[string]interface{} + if err := decoder.Decode(&data); err != nil { + return err + } + + { + v, ok := data["@context"] + if ! ok { + return &DecodeError{path, "@context missing"} + } + + sub_path := path.PushPath("@context") + value, ok := v.(string) + if ! ok { + return &DecodeError{sub_path, "@context must be a string, or list of string"} + } + if value != "" { + return &DecodeError{sub_path, "Wrong context URL '" + value + "'"} + } + } + + delete(data, "@context") + + decodeProxy := func (data any, path Path, context map[string]string) (SHACLObject, error) { + return DecodeSHACLObject[SHACLObject](data, path, context, nil) + } + + _, has_graph := data["@graph"] + if has_graph { + for k, v := range data { + switch k { + case "@graph": { + objs, err := DecodeList[SHACLObject]( + v, + path.PushPath("@graph"), + map[string]string{}, + decodeProxy, + ) + + if err != nil { + return err + } + + for _, obj := range objs { + self.AddObject(obj) + } + } + + default: + return &DecodeError{path, "Unknown property '" + k + "'"} + } + } + } else { + obj, err := decodeProxy(data, path, map[string]string{}) + if err != nil { + return err + } + + self.AddObject(obj) + } + + return nil +} + +func (self *SHACLObjectSetObject) Encode(encoder *json.Encoder) error { + data := make(map[string]interface{}) + data["@context"] = "" + path := Path{} + state := EncodeState{ + Written: make(map[SHACLObject]bool), + } + + ref_counts := make(map[SHACLObject]int) + + visit := func (path Path, v any) { + r, ok := v.(Ref[SHACLObject]) + if ! ok { + return + } + + if ! r.IsObj() { + return + } + + o := r.GetObj() + + // Remove blank nodes for reassignment + if o.ID().IsSet() && IsBlankNode(o.ID().Get()) { + o.ID().Delete() + } + + ref_counts[o] = ref_counts[o] + 1 + } + + self.Walk(visit) + + blank_count := 0 + for o, count := range ref_counts { + if count <= 1 { + continue + } + + if o.ID().IsSet() { + continue + } + + o.ID().Set(fmt.Sprintf("_:%d", blank_count)) + blank_count += 1 + } + + if len(self.objects) == 1 { + err := self.objects[0].EncodeProperties(data, path, &state) + if err != nil { + return err + } + } else if len(self.objects) > 1 { + // All objects directly added to the object set should be written as + // top level objects, so mark then as written until they are ready to + // be serialized, which will force them to be referenced by IRI until + // we are ready + for _, o := range self.objects { + state.Written[o] = true + } + + graph_path := path.PushPath("@graph") + lst := []interface{}{} + for idx, o := range self.objects { + // Remove this object from the written set now so it gets serialized + delete(state.Written, o) + + d, err := EncodeSHACLObject(o, graph_path.PushIndex(idx), &state) + if err != nil { + return err + } + lst = append(lst, d) + } + + data["@graph"] = lst + } + + return encoder.Encode(data) +} + +func (self *SHACLObjectSetObject) Walk(visit Visit) { + path := Path{} + visited := map[SHACLObject]bool{} + + visit_proxy := func (path Path, v any) { + switch v.(type) { + case Ref[SHACLObject]: + r := v.(Ref[SHACLObject]) + if ! r.IsObj() { + visit(path, v) + return + } + + o := r.GetObj() + _, ok := visited[o] + if ok { + return + } + visited[o] = true + visit(path, v) + o.Walk(path, visit) + return + + default: + visit(path, v) + return + } + } + + for idx, o := range(self.objects) { + sub_path := path.PushIndex(idx) + visit_proxy(sub_path, MakeObjectRef(o)) + } +} + +func (self *SHACLObjectSetObject) Validate(handler ErrorHandler) bool { + valid := true + + visit_proxy := func (path Path, v any) { + r, ok := v.(Ref[SHACLObject]) + if ! ok { + return + } + + if ! r.IsObj() { + return + } + + if ! r.GetObj().Validate(path, handler) { + valid = false + } + } + + self.Walk(visit_proxy) + + return valid +} + +func NewSHACLObjectSet() SHACLObjectSet { + os := SHACLObjectSetObject{} + return &os +} + +func DecodeAny(data any, path Path, context map[string]string) (any, error) { + switch data.(type) { + case map[string]interface{}: + return DecodeRef[SHACLObject](data, path, context, nil) + case string: + return DecodeString(data, path, context) + case int: + return DecodeInteger(data, path, context) + case float64: + return DecodeFloat(data, path, context) + case bool: + return DecodeBoolean(data, path, context) + case []interface{}: + return DecodeList[any](data, path, context, DecodeAny) + default: + return nil, &DecodeError{path, "Unknown type "+ reflect.TypeOf(data).Name()} + } +} + +func DecodeSHACLObject[T SHACLObject](data any, path Path, context map[string]string, targetType SHACLType) (T, error) { + dict, ok := data.(map[string]interface{}) + if ! ok { + return *new(T), &DecodeError{path, "Expected dictionary or string. Got " + reflect.TypeOf(data).Name()} + } + + var v interface{} + v, ok = dict["@type"] + if ! ok { + v, ok = dict["@type"] + if ! ok { + return *new(T), &DecodeError{path, "type missing"} + } + } + + var type_iri string + var create_type SHACLType + + type_iri, ok = v.(string) + if ! ok { + return *new(T), &DecodeError{path, "Wrong type for @type. Got " + reflect.TypeOf(v).Name()} + } + + iri_typ, ok := objectTypes[type_iri] + if ok { + if targetType != nil && !iri_typ.IsSubClassOf(targetType) { + return *new(T), &DecodeError{path, "Type " + type_iri + " is not valid where " + + targetType.GetTypeIRI() + " is expected"} + } + + if iri_typ.IsAbstract() { + return *new(T), &DecodeError{path, "Unable to create abstract type '" + type_iri + "'"} + } + + create_type = iri_typ + } else if targetType != nil && targetType.IsExtensible() { + // An extensible type is expected, so make one of the correct type + // + // Note: An abstract extensible class is actually allowed to be created + // here + create_type = targetType + } else { + if IsIRI(type_iri) { + // It's not clear exactly which type should be created. Search through + // all types and collect a list of possible Extensible types that are + // valid in this location. + possible := []SHACLType{} + for _, v := range objectTypes { + if ! v.IsExtensible() { + continue + } + + if v.IsAbstract() { + continue + } + + // If a type was specified, only subclasses of that type are + // allowed + if targetType != nil && ! v.IsSubClassOf(targetType) { + continue + } + + possible = append(possible, v) + } + + // Sort for determinism + sort.Slice(possible, func(i, j int) bool { + return possible[i].GetTypeIRI() < possible[j].GetTypeIRI() + }) + + for _, t := range(possible) { + // Ignore errors + o, err := DecodeSHACLObject[T](data, path, context, t) + if err == nil { + o.setTypeIRI(type_iri) + return o, nil + } + } + } + return *new(T), &DecodeError{path, "Unable to create object of type '" + type_iri + "' (no matching extensible object)"} + } + + obj, ok := create_type.Create().(T) + if ! ok { + return *new(T), &DecodeError{path, "Unable to create object of type '" + type_iri + "'"} + } + obj.setTypeIRI(type_iri) + + for k, v := range dict { + if k == "@type" { + continue + } + if k == "@type" { + continue + } + + sub_path := path.PushPath(k) + found, err := create_type.DecodeProperty(obj, k, v, sub_path) + if err != nil { + return *new(T), err + } + if ! found { + return *new(T), &DecodeError{path, "Unknown property '" + k + "'"} + } + } + + return obj, nil +} + +func DecodeRef[T SHACLObject](data any, path Path, context map[string]string, typ SHACLType) (Ref[T], error) { + switch data.(type) { + case string: + s, err := DecodeIRI(data, path, context) + if err != nil { + return nil, err + } + return MakeIRIRef[T](s), nil + } + + obj, err := DecodeSHACLObject[T](data, path, context, typ) + if err != nil { + return nil, err + } + + return MakeObjectRef[T](obj), nil +} + +func EncodeRef[T SHACLObject](value Ref[T], path Path, context map[string]string, state *EncodeState) (any, error) { + if value.IsIRI() { + v := value.GetIRI() + compact, ok := context[v] + if ok { + return compact, nil + } + return v, nil + } + return EncodeSHACLObject(value.GetObj(), path, state) +} + +func DecodeString(data any, path Path, context map[string]string) (string, error) { + v, ok := data.(string) + if ! ok { + return v, &DecodeError{path, "String expected. Got " + reflect.TypeOf(data).Name()} + } + return v, nil +} + +func EncodeString(value string, path Path, context map[string]string, state *EncodeState) (any, error) { + return value, nil +} + +func DecodeIRI(data any, path Path, context map[string]string) (string, error) { + s, err := DecodeString(data, path, context) + if err != nil { + return s, err + } + + for k, v := range context { + if s == v { + s = k + break + } + } + + if ! IsBlankNode(s) && ! IsIRI(s) { + return s, &DecodeError{path, "Must be blank node or IRI. Got '" + s + "'"} + } + + return s, nil +} + +func EncodeIRI(value string, path Path, context map[string]string, state *EncodeState) (any, error) { + compact, ok := context[value] + if ok { + return compact, nil + } + return value, nil +} + +func DecodeBoolean(data any, path Path, context map[string]string) (bool, error) { + v, ok := data.(bool) + if ! ok { + return v, &DecodeError{path, "Boolean expected. Got " + reflect.TypeOf(data).Name()} + } + return v, nil +} + +func EncodeBoolean(value bool, path Path, context map[string]string, state *EncodeState) (any, error) { + return value, nil +} + +func DecodeInteger(data any, path Path, context map[string]string) (int, error) { + switch data.(type) { + case int: + return data.(int), nil + case float64: + v := data.(float64) + if v == float64(int64(v)) { + return int(v), nil + } + return 0, &DecodeError{path, "Value must be an integer. Got " + fmt.Sprintf("%f", v)} + default: + return 0, &DecodeError{path, "Integer expected. Got " + reflect.TypeOf(data).Name()} + } +} + +func EncodeInteger(value int, path Path, context map[string]string, state *EncodeState) (any, error) { + return value, nil +} + +func DecodeFloat(data any, path Path, context map[string]string) (float64, error) { + switch data.(type) { + case float64: + return data.(float64), nil + case string: + v, err := strconv.ParseFloat(data.(string), 64) + if err != nil { + return 0, err + } + return v, nil + default: + return 0, &DecodeError{path, "Float expected. Got " + reflect.TypeOf(data).Name()} + } +} + +func EncodeFloat(value float64, path Path, context map[string]string, state *EncodeState) (any, error) { + return strconv.FormatFloat(value, 'f', -1, 64), nil +} + +const UtcFormatStr = "%Y-%m-%dT%H:%M:%SZ" +const TzFormatStr = "%Y-%m-%dT%H:%M:%S%:z" + +func decodeDateTimeString(data any, path Path, re *regexp.Regexp) (time.Time, error) { + v, ok := data.(string) + if ! ok { + return time.Time{}, &DecodeError{path, "String expected. Got " + reflect.TypeOf(data).Name()} + } + + match := re.FindStringSubmatch(v) + + if match == nil { + return time.Time{}, &DecodeError{path, "Invalid date time string '" + v + "'"} + } + + var format string + s := match[1] + tzstr := match[2] + + switch tzstr { + case "Z": + s += "+00:00" + format = "%Y-%m-%dT%H:%M:%S%:z" + case "": + format = "%Y-%m-%dT%H:%M:%S" + default: + s += tzstr + format = "%Y-%m-%dT%H:%M:%S%:z" + } + + t, err := strftime.Parse(format, v) + if err != nil { + return time.Time{}, &DecodeError{path, "Invalid date time string '" + v + "': " + err.Error()} + } + return t, nil +} + +var dateTimeRegex = regexp.MustCompile(`^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})(Z|[+-]\d{2}:\d{2})?$`) +func DecodeDateTime(data any, path Path, context map[string]string) (time.Time, error) { + return decodeDateTimeString(data, path, dateTimeRegex) +} + +var dateTimeStampRegex = regexp.MustCompile(`^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})(Z|[+-]\d{2}:\d{2})$`) +func DecodeDateTimeStamp(data any, path Path, context map[string]string) (time.Time, error) { + return decodeDateTimeString(data, path, dateTimeStampRegex) +} + +func EncodeDateTime(value time.Time, path Path, context map[string]string, state *EncodeState) (any, error) { + if value.Location() == time.UTC { + return strftime.Format(UtcFormatStr, value), nil + } + return strftime.Format(TzFormatStr, value), nil +} + +func DecodeList[T any](data any, path Path, context map[string]string, f func (any, Path, map[string]string) (T, error)) ([]T, error) { + lst, ok := data.([]interface{}) + if ! ok { + return nil, &DecodeError{path, "Must be a list"} + } + + var result []T + for idx, v := range lst { + sub_path := path.PushIndex(idx) + item, err := f(v, sub_path, context) + if err != nil { + return nil, err + } + result = append(result, item) + } + + return result, nil +} + +func EncodeList[T any](value []T, path Path, context map[string]string, state *EncodeState, f func (T, Path, map[string]string, *EncodeState) (any, error)) (any, error) { + lst := []any{} + for idx, v := range value { + val, err := f(v, path.PushIndex(idx), context, state) + if err != nil { + return lst, err + } + + lst = append(lst, val) + } + return lst, nil +} + +// IRI Validation +func IsIRI(iri string) bool { + if strings.HasPrefix(iri, "_:") { + return false + } + if strings.Contains(iri, ":") { + return true + } + return false +} + +func IsBlankNode(iri string) bool { + return strings.HasPrefix(iri, "_:") +} + +// Optional +type Optional[T any] struct { + value *T +} + +func (self Optional[T]) Get() T { + return *self.value +} + +func (self Optional[T]) GetDefault(val T) T { + if ! self.IsSet() { + return val + } + return *self.value +} + +func (self Optional[T]) IsSet() bool { + return self.value != nil +} + +func NewOptional[T any](value T) Optional[T] { + return Optional[T]{&value} +} + +func NewEmptyOptional[T any]() Optional[T] { + return Optional[T]{nil} +} + +// Validator +type Validator[T any] interface { + Check(T, string) error +} + +func ValueToString(val any) string { + switch val.(type) { + case string: + return val.(string) + case int: + return strconv.Itoa(val.(int)) + case time.Time: + t := val.(time.Time) + if t.Location() == time.UTC { + return strftime.Format(UtcFormatStr, t) + } + return strftime.Format(TzFormatStr, t) + } + panic("Unsupported Type " + reflect.TypeOf(val).Name()) +} + + +// ID Validator +type IDValidator struct {} + +func (self IDValidator) Check(val string, name string) error { + if ! IsIRI(val) && ! IsBlankNode(val) { + return &ValidationError{name, "Must be an IRI or a Blank Node"} + } + return nil +} + + +// Regex Validator +type RegexValidator[T int | time.Time | string] struct { + Regex string +} + +func (self RegexValidator[T]) Check(val T, name string) error { + s := ValueToString(val) + + m, err := regexp.MatchString(self.Regex, s) + if err != nil { + return err + } + if ! m { + return &ValidationError{name, "Value '" + s + "' does not match pattern"} + } + return nil +} + +// Integer Min Validator +type IntegerMinValidator struct { + Min int +} + +func (self IntegerMinValidator) Check(val int, name string) error { + if val < self.Min { + return &ValidationError{name, "Value " + strconv.Itoa(val) + " is less than minimum " + strconv.Itoa(self.Min)} + } + return nil +} + +// Integer Max Validator +type IntegerMaxValidator struct { + Max int +} + +func (self IntegerMaxValidator) Check(val int, name string) error { + if val > self.Max { + return &ValidationError{name, "Value " + strconv.Itoa(val) + " is greater than maximum" + strconv.Itoa(self.Max)} + } + return nil +} + +// Enum Validator +type EnumValidator struct { + Values []string +} + +func (self EnumValidator) Check(val string, name string) error { + for _, v := range self.Values { + if val == v { + return nil + } + } + return &ValidationError{name, "Value '" + val + "' is not a valid enumerated value" } +} + +// Property +type PropertyInterface[T any] interface { + Get() T + Set(val T) error + Delete() + IsSet() bool + Walk(path Path, visit Visit) +} + +type Property[T any] struct { + value Optional[T] + name string + validators []Validator[T] +} + +func NewProperty[T any](name string, validators []Validator[T]) Property[T] { + return Property[T]{ + value: NewEmptyOptional[T](), + name: name, + validators: validators, + } +} + +func (self *Property[T]) Get() T { + return self.value.Get() +} + +func (self *Property[T]) Set(val T) error { + for _, validator := range self.validators { + err := validator.Check(val, self.name) + if err != nil { + return err + } + } + + self.value = NewOptional(val) + return nil +} + +func (self *Property[T]) Delete() { + self.value = NewEmptyOptional[T]() +} + +func (self *Property[T]) IsSet() bool { + return self.value.IsSet() +} + +func (self *Property[T]) Check(path Path, handler ErrorHandler) bool { + if ! self.value.IsSet() { + return true + } + + var valid bool + valid = true + + for _, validator := range self.validators { + err := validator.Check(self.value.Get(), self.name) + if err != nil { + if handler != nil { + handler.HandleError(err, path) + } + valid = false + } + } + return valid +} + +func (self *Property[T]) Walk(path Path, visit Visit) { + if ! self.value.IsSet() { + return + } + + visit(path.PushPath(self.name), self.value.Get()) +} + +// Ref Property +type RefPropertyInterface[T SHACLObject] interface { + PropertyInterface[Ref[T]] + + SetObj(val T) error + SetIRI(iri string) error + + GetIRI() string + GetObj() T + IsObj() bool + IsIRI() bool +} + +type RefProperty[T SHACLObject] struct { + Property[Ref[T]] +} + +func NewRefProperty[T SHACLObject](name string, validators []Validator[Ref[T]]) RefProperty[T] { + return RefProperty[T]{ + Property: Property[Ref[T]]{ + value: NewEmptyOptional[Ref[T]](), + name: name, + validators: validators, + }, + } +} + +func (self *RefProperty[T]) SetObj(obj T) error { + // Shorthand to assign an object by making a reference to it + return self.Set(MakeObjectRef(obj)) +} + +func (self *RefProperty[T]) SetIRI(iri string) error { + // Shorthand to assign an IRI by making a reference to it + return self.Set(MakeIRIRef[T](iri)) +} + +func (self *RefProperty[T]) GetIRI() string { + // Shorthand to get the IRI value + return self.Get().GetIRI() +} + +func (self *RefProperty[T]) GetObj() T { + // Shorthand to get the Object value + return self.Get().GetObj() +} + +func (self *RefProperty[T]) IsSet() bool { + return self.Property.IsSet() && self.Get().IsSet() +} + +func (self *RefProperty[T]) IsObj() bool { + // Shorthand to check if the property references an object + return self.Property.IsSet() && self.Get().IsObj() +} + +func (self *RefProperty[T]) IsIRI() bool { + // Shorthand to check if the property references an IRI + return self.Property.IsSet() && self.Get().IsIRI() +} + +func (self *RefProperty[T]) Walk(path Path, visit Visit) { + if ! self.IsSet() { + return + } + + r, err := ConvertRef[SHACLObject](self.value.Get()) + if err != nil { + return + } + + visit(path.PushPath(self.name), r) +} + +// List Property +type ListPropertyInterface[T any] interface { + Get() []T + Set(val []T) error + Append(val T) error + Delete() + Walk(path Path, visit Visit) + IsSet() bool +} + +type ListProperty[T any] struct { + value []T + name string + validators []Validator[T] +} + +func NewListProperty[T any](name string, validators []Validator[T]) ListProperty[T] { + return ListProperty[T]{ + value: []T{}, + name: name, + validators: validators, + } +} + +func (self *ListProperty[T]) Get() []T { + return self.value +} + +func (self *ListProperty[T]) Set(val []T) error { + for _, v := range val { + for _, validator := range self.validators { + err := validator.Check(v, self.name) + if err != nil { + return err + } + } + } + + self.value = val + return nil +} + +func (self *ListProperty[T]) Append(val T) error { + for _, validator := range self.validators { + err := validator.Check(val, self.name) + if err != nil { + return err + } + } + + self.value = append(self.value, val) + return nil +} + +func (self *ListProperty[T]) Delete() { + self.value = []T{} +} + +func (self *ListProperty[T]) IsSet() bool { + return self.value != nil && len(self.value) > 0 +} + +func (self *ListProperty[T]) Check(path Path, handler ErrorHandler) bool { + var valid bool + valid = true + + for idx, v := range self.value { + for _, validator := range self.validators { + err := validator.Check(v, self.name) + if err != nil { + if handler != nil { + handler.HandleError(err, path.PushIndex(idx)) + } + valid = false + } + } + } + return valid +} + +func (self *ListProperty[T]) Walk(path Path, visit Visit) { + sub_path := path.PushPath(self.name) + + for idx, v := range self.value { + visit(sub_path.PushIndex(idx), v) + } +} + +type RefListProperty[T SHACLObject] struct { + ListProperty[Ref[T]] +} + +func NewRefListProperty[T SHACLObject](name string, validators []Validator[Ref[T]]) RefListProperty[T] { + return RefListProperty[T]{ + ListProperty: ListProperty[Ref[T]]{ + value: []Ref[T]{}, + name: name, + validators: validators, + }, + } +} + +func (self *RefListProperty[T]) Walk(path Path, visit Visit) { + sub_path := path.PushPath(self.name) + + for idx, v := range self.value { + r, err := ConvertRef[SHACLObject](v) + if err != nil { + visit(sub_path.PushIndex(idx), r) + } + } +} + + +// An Abstract class +type HttpExampleOrgAbstractClassObject struct { + SHACLObjectBase + +} + + +type HttpExampleOrgAbstractClassObjectType struct { + SHACLTypeBase +} +var httpExampleOrgAbstractClassType HttpExampleOrgAbstractClassObjectType + +func DecodeHttpExampleOrgAbstractClass (data any, path Path, context map[string]string) (Ref[HttpExampleOrgAbstractClass], error) { + return DecodeRef[HttpExampleOrgAbstractClass](data, path, context, httpExampleOrgAbstractClassType) +} + +func (self HttpExampleOrgAbstractClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgAbstractClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgAbstractClassObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgAbstractClassObject(&HttpExampleOrgAbstractClassObject{}, self) +} + +func ConstructHttpExampleOrgAbstractClassObject(o *HttpExampleOrgAbstractClassObject, typ SHACLType) *HttpExampleOrgAbstractClassObject { + ConstructSHACLObjectBase(&o.SHACLObjectBase, typ) + return o +} + +type HttpExampleOrgAbstractClass interface { + SHACLObject +} + + + +func (self *HttpExampleOrgAbstractClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.SHACLObjectBase.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *HttpExampleOrgAbstractClassObject) Walk(path Path, visit Visit) { + self.SHACLObjectBase.Walk(path, visit) +} + + + +func (self *HttpExampleOrgAbstractClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.SHACLObjectBase.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} +type HttpExampleOrgAbstractShClassObject struct { + SHACLObjectBase + +} + + +type HttpExampleOrgAbstractShClassObjectType struct { + SHACLTypeBase +} +var httpExampleOrgAbstractShClassType HttpExampleOrgAbstractShClassObjectType + +func DecodeHttpExampleOrgAbstractShClass (data any, path Path, context map[string]string) (Ref[HttpExampleOrgAbstractShClass], error) { + return DecodeRef[HttpExampleOrgAbstractShClass](data, path, context, httpExampleOrgAbstractShClassType) +} + +func (self HttpExampleOrgAbstractShClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgAbstractShClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgAbstractShClassObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgAbstractShClassObject(&HttpExampleOrgAbstractShClassObject{}, self) +} + +func ConstructHttpExampleOrgAbstractShClassObject(o *HttpExampleOrgAbstractShClassObject, typ SHACLType) *HttpExampleOrgAbstractShClassObject { + ConstructSHACLObjectBase(&o.SHACLObjectBase, typ) + return o +} + +type HttpExampleOrgAbstractShClass interface { + SHACLObject +} + + + +func (self *HttpExampleOrgAbstractShClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.SHACLObjectBase.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *HttpExampleOrgAbstractShClassObject) Walk(path Path, visit Visit) { + self.SHACLObjectBase.Walk(path, visit) +} + + + +func (self *HttpExampleOrgAbstractShClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.SHACLObjectBase.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// An Abstract class using the SPDX type +type HttpExampleOrgAbstractSpdxClassObject struct { + SHACLObjectBase + +} + + +type HttpExampleOrgAbstractSpdxClassObjectType struct { + SHACLTypeBase +} +var httpExampleOrgAbstractSpdxClassType HttpExampleOrgAbstractSpdxClassObjectType + +func DecodeHttpExampleOrgAbstractSpdxClass (data any, path Path, context map[string]string) (Ref[HttpExampleOrgAbstractSpdxClass], error) { + return DecodeRef[HttpExampleOrgAbstractSpdxClass](data, path, context, httpExampleOrgAbstractSpdxClassType) +} + +func (self HttpExampleOrgAbstractSpdxClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgAbstractSpdxClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgAbstractSpdxClassObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgAbstractSpdxClassObject(&HttpExampleOrgAbstractSpdxClassObject{}, self) +} + +func ConstructHttpExampleOrgAbstractSpdxClassObject(o *HttpExampleOrgAbstractSpdxClassObject, typ SHACLType) *HttpExampleOrgAbstractSpdxClassObject { + ConstructSHACLObjectBase(&o.SHACLObjectBase, typ) + return o +} + +type HttpExampleOrgAbstractSpdxClass interface { + SHACLObject +} + + + +func (self *HttpExampleOrgAbstractSpdxClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.SHACLObjectBase.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *HttpExampleOrgAbstractSpdxClassObject) Walk(path Path, visit Visit) { + self.SHACLObjectBase.Walk(path, visit) +} + + + +func (self *HttpExampleOrgAbstractSpdxClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.SHACLObjectBase.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// A concrete class +type HttpExampleOrgConcreteClassObject struct { + HttpExampleOrgAbstractClassObject + +} + + +type HttpExampleOrgConcreteClassObjectType struct { + SHACLTypeBase +} +var httpExampleOrgConcreteClassType HttpExampleOrgConcreteClassObjectType + +func DecodeHttpExampleOrgConcreteClass (data any, path Path, context map[string]string) (Ref[HttpExampleOrgConcreteClass], error) { + return DecodeRef[HttpExampleOrgConcreteClass](data, path, context, httpExampleOrgConcreteClassType) +} + +func (self HttpExampleOrgConcreteClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgConcreteClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgConcreteClassObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgConcreteClassObject(&HttpExampleOrgConcreteClassObject{}, self) +} + +func ConstructHttpExampleOrgConcreteClassObject(o *HttpExampleOrgConcreteClassObject, typ SHACLType) *HttpExampleOrgConcreteClassObject { + ConstructHttpExampleOrgAbstractClassObject(&o.HttpExampleOrgAbstractClassObject, typ) + return o +} + +type HttpExampleOrgConcreteClass interface { + HttpExampleOrgAbstractClass +} + + +func MakeHttpExampleOrgConcreteClass() HttpExampleOrgConcreteClass { + return ConstructHttpExampleOrgConcreteClassObject(&HttpExampleOrgConcreteClassObject{}, httpExampleOrgConcreteClassType) +} + +func MakeHttpExampleOrgConcreteClassRef() Ref[HttpExampleOrgConcreteClass] { + o := MakeHttpExampleOrgConcreteClass() + return MakeObjectRef[HttpExampleOrgConcreteClass](o) +} + +func (self *HttpExampleOrgConcreteClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.HttpExampleOrgAbstractClassObject.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *HttpExampleOrgConcreteClassObject) Walk(path Path, visit Visit) { + self.HttpExampleOrgAbstractClassObject.Walk(path, visit) +} + + + +func (self *HttpExampleOrgConcreteClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.HttpExampleOrgAbstractClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// A concrete class +type HttpExampleOrgConcreteShClassObject struct { + HttpExampleOrgAbstractShClassObject + +} + + +type HttpExampleOrgConcreteShClassObjectType struct { + SHACLTypeBase +} +var httpExampleOrgConcreteShClassType HttpExampleOrgConcreteShClassObjectType + +func DecodeHttpExampleOrgConcreteShClass (data any, path Path, context map[string]string) (Ref[HttpExampleOrgConcreteShClass], error) { + return DecodeRef[HttpExampleOrgConcreteShClass](data, path, context, httpExampleOrgConcreteShClassType) +} + +func (self HttpExampleOrgConcreteShClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgConcreteShClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgConcreteShClassObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgConcreteShClassObject(&HttpExampleOrgConcreteShClassObject{}, self) +} + +func ConstructHttpExampleOrgConcreteShClassObject(o *HttpExampleOrgConcreteShClassObject, typ SHACLType) *HttpExampleOrgConcreteShClassObject { + ConstructHttpExampleOrgAbstractShClassObject(&o.HttpExampleOrgAbstractShClassObject, typ) + return o +} + +type HttpExampleOrgConcreteShClass interface { + HttpExampleOrgAbstractShClass +} + + +func MakeHttpExampleOrgConcreteShClass() HttpExampleOrgConcreteShClass { + return ConstructHttpExampleOrgConcreteShClassObject(&HttpExampleOrgConcreteShClassObject{}, httpExampleOrgConcreteShClassType) +} + +func MakeHttpExampleOrgConcreteShClassRef() Ref[HttpExampleOrgConcreteShClass] { + o := MakeHttpExampleOrgConcreteShClass() + return MakeObjectRef[HttpExampleOrgConcreteShClass](o) +} + +func (self *HttpExampleOrgConcreteShClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.HttpExampleOrgAbstractShClassObject.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *HttpExampleOrgConcreteShClassObject) Walk(path Path, visit Visit) { + self.HttpExampleOrgAbstractShClassObject.Walk(path, visit) +} + + + +func (self *HttpExampleOrgConcreteShClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.HttpExampleOrgAbstractShClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// A concrete class +type HttpExampleOrgConcreteSpdxClassObject struct { + HttpExampleOrgAbstractSpdxClassObject + +} + + +type HttpExampleOrgConcreteSpdxClassObjectType struct { + SHACLTypeBase +} +var httpExampleOrgConcreteSpdxClassType HttpExampleOrgConcreteSpdxClassObjectType + +func DecodeHttpExampleOrgConcreteSpdxClass (data any, path Path, context map[string]string) (Ref[HttpExampleOrgConcreteSpdxClass], error) { + return DecodeRef[HttpExampleOrgConcreteSpdxClass](data, path, context, httpExampleOrgConcreteSpdxClassType) +} + +func (self HttpExampleOrgConcreteSpdxClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgConcreteSpdxClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgConcreteSpdxClassObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgConcreteSpdxClassObject(&HttpExampleOrgConcreteSpdxClassObject{}, self) +} + +func ConstructHttpExampleOrgConcreteSpdxClassObject(o *HttpExampleOrgConcreteSpdxClassObject, typ SHACLType) *HttpExampleOrgConcreteSpdxClassObject { + ConstructHttpExampleOrgAbstractSpdxClassObject(&o.HttpExampleOrgAbstractSpdxClassObject, typ) + return o +} + +type HttpExampleOrgConcreteSpdxClass interface { + HttpExampleOrgAbstractSpdxClass +} + + +func MakeHttpExampleOrgConcreteSpdxClass() HttpExampleOrgConcreteSpdxClass { + return ConstructHttpExampleOrgConcreteSpdxClassObject(&HttpExampleOrgConcreteSpdxClassObject{}, httpExampleOrgConcreteSpdxClassType) +} + +func MakeHttpExampleOrgConcreteSpdxClassRef() Ref[HttpExampleOrgConcreteSpdxClass] { + o := MakeHttpExampleOrgConcreteSpdxClass() + return MakeObjectRef[HttpExampleOrgConcreteSpdxClass](o) +} + +func (self *HttpExampleOrgConcreteSpdxClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.HttpExampleOrgAbstractSpdxClassObject.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *HttpExampleOrgConcreteSpdxClassObject) Walk(path Path, visit Visit) { + self.HttpExampleOrgAbstractSpdxClassObject.Walk(path, visit) +} + + + +func (self *HttpExampleOrgConcreteSpdxClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.HttpExampleOrgAbstractSpdxClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// An enumerated type +type HttpExampleOrgEnumTypeObject struct { + SHACLObjectBase + +} + +// The foo value of enumType +const HttpExampleOrgEnumTypeFoo = "http://example.org/enumType/foo" +// The bar value of enumType +const HttpExampleOrgEnumTypeBar = "http://example.org/enumType/bar" +// This value has no label +const HttpExampleOrgEnumTypeNolabel = "http://example.org/enumType/nolabel" + +type HttpExampleOrgEnumTypeObjectType struct { + SHACLTypeBase +} +var httpExampleOrgEnumTypeType HttpExampleOrgEnumTypeObjectType + +func DecodeHttpExampleOrgEnumType (data any, path Path, context map[string]string) (Ref[HttpExampleOrgEnumType], error) { + return DecodeRef[HttpExampleOrgEnumType](data, path, context, httpExampleOrgEnumTypeType) +} + +func (self HttpExampleOrgEnumTypeObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgEnumType) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgEnumTypeObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgEnumTypeObject(&HttpExampleOrgEnumTypeObject{}, self) +} + +func ConstructHttpExampleOrgEnumTypeObject(o *HttpExampleOrgEnumTypeObject, typ SHACLType) *HttpExampleOrgEnumTypeObject { + ConstructSHACLObjectBase(&o.SHACLObjectBase, typ) + return o +} + +type HttpExampleOrgEnumType interface { + SHACLObject +} + + +func MakeHttpExampleOrgEnumType() HttpExampleOrgEnumType { + return ConstructHttpExampleOrgEnumTypeObject(&HttpExampleOrgEnumTypeObject{}, httpExampleOrgEnumTypeType) +} + +func MakeHttpExampleOrgEnumTypeRef() Ref[HttpExampleOrgEnumType] { + o := MakeHttpExampleOrgEnumType() + return MakeObjectRef[HttpExampleOrgEnumType](o) +} + +func (self *HttpExampleOrgEnumTypeObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.SHACLObjectBase.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *HttpExampleOrgEnumTypeObject) Walk(path Path, visit Visit) { + self.SHACLObjectBase.Walk(path, visit) +} + + + +func (self *HttpExampleOrgEnumTypeObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.SHACLObjectBase.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// An extensible abstract class +type HttpExampleOrgExtensibleAbstractClassObject struct { + SHACLObjectBase + SHACLExtensibleBase + +} + + +type HttpExampleOrgExtensibleAbstractClassObjectType struct { + SHACLTypeBase +} +var httpExampleOrgExtensibleAbstractClassType HttpExampleOrgExtensibleAbstractClassObjectType + +func DecodeHttpExampleOrgExtensibleAbstractClass (data any, path Path, context map[string]string) (Ref[HttpExampleOrgExtensibleAbstractClass], error) { + return DecodeRef[HttpExampleOrgExtensibleAbstractClass](data, path, context, httpExampleOrgExtensibleAbstractClassType) +} + +func (self HttpExampleOrgExtensibleAbstractClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgExtensibleAbstractClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgExtensibleAbstractClassObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgExtensibleAbstractClassObject(&HttpExampleOrgExtensibleAbstractClassObject{}, self) +} + +func ConstructHttpExampleOrgExtensibleAbstractClassObject(o *HttpExampleOrgExtensibleAbstractClassObject, typ SHACLType) *HttpExampleOrgExtensibleAbstractClassObject { + ConstructSHACLObjectBase(&o.SHACLObjectBase, typ) + return o +} + +type HttpExampleOrgExtensibleAbstractClass interface { + SHACLObject +} + + + +func (self *HttpExampleOrgExtensibleAbstractClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.SHACLObjectBase.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *HttpExampleOrgExtensibleAbstractClassObject) Walk(path Path, visit Visit) { + self.SHACLObjectBase.Walk(path, visit) +} + + + +func (self *HttpExampleOrgExtensibleAbstractClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.SHACLObjectBase.EncodeProperties(data, path, state); err != nil { + return err + } + self.SHACLExtensibleBase.EncodeExtProperties(data, path) + return nil +} + +// A class with an ID alias +type HttpExampleOrgIdPropClassObject struct { + SHACLObjectBase + +} + + +type HttpExampleOrgIdPropClassObjectType struct { + SHACLTypeBase +} +var httpExampleOrgIdPropClassType HttpExampleOrgIdPropClassObjectType + +func DecodeHttpExampleOrgIdPropClass (data any, path Path, context map[string]string) (Ref[HttpExampleOrgIdPropClass], error) { + return DecodeRef[HttpExampleOrgIdPropClass](data, path, context, httpExampleOrgIdPropClassType) +} + +func (self HttpExampleOrgIdPropClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgIdPropClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgIdPropClassObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgIdPropClassObject(&HttpExampleOrgIdPropClassObject{}, self) +} + +func ConstructHttpExampleOrgIdPropClassObject(o *HttpExampleOrgIdPropClassObject, typ SHACLType) *HttpExampleOrgIdPropClassObject { + ConstructSHACLObjectBase(&o.SHACLObjectBase, typ) + return o +} + +type HttpExampleOrgIdPropClass interface { + SHACLObject +} + + +func MakeHttpExampleOrgIdPropClass() HttpExampleOrgIdPropClass { + return ConstructHttpExampleOrgIdPropClassObject(&HttpExampleOrgIdPropClassObject{}, httpExampleOrgIdPropClassType) +} + +func MakeHttpExampleOrgIdPropClassRef() Ref[HttpExampleOrgIdPropClass] { + o := MakeHttpExampleOrgIdPropClass() + return MakeObjectRef[HttpExampleOrgIdPropClass](o) +} + +func (self *HttpExampleOrgIdPropClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.SHACLObjectBase.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *HttpExampleOrgIdPropClassObject) Walk(path Path, visit Visit) { + self.SHACLObjectBase.Walk(path, visit) +} + + + +func (self *HttpExampleOrgIdPropClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.SHACLObjectBase.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// A class that inherits its idPropertyName from the parent +type HttpExampleOrgInheritedIdPropClassObject struct { + HttpExampleOrgIdPropClassObject + +} + + +type HttpExampleOrgInheritedIdPropClassObjectType struct { + SHACLTypeBase +} +var httpExampleOrgInheritedIdPropClassType HttpExampleOrgInheritedIdPropClassObjectType + +func DecodeHttpExampleOrgInheritedIdPropClass (data any, path Path, context map[string]string) (Ref[HttpExampleOrgInheritedIdPropClass], error) { + return DecodeRef[HttpExampleOrgInheritedIdPropClass](data, path, context, httpExampleOrgInheritedIdPropClassType) +} + +func (self HttpExampleOrgInheritedIdPropClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgInheritedIdPropClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgInheritedIdPropClassObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgInheritedIdPropClassObject(&HttpExampleOrgInheritedIdPropClassObject{}, self) +} + +func ConstructHttpExampleOrgInheritedIdPropClassObject(o *HttpExampleOrgInheritedIdPropClassObject, typ SHACLType) *HttpExampleOrgInheritedIdPropClassObject { + ConstructHttpExampleOrgIdPropClassObject(&o.HttpExampleOrgIdPropClassObject, typ) + return o +} + +type HttpExampleOrgInheritedIdPropClass interface { + HttpExampleOrgIdPropClass +} + + +func MakeHttpExampleOrgInheritedIdPropClass() HttpExampleOrgInheritedIdPropClass { + return ConstructHttpExampleOrgInheritedIdPropClassObject(&HttpExampleOrgInheritedIdPropClassObject{}, httpExampleOrgInheritedIdPropClassType) +} + +func MakeHttpExampleOrgInheritedIdPropClassRef() Ref[HttpExampleOrgInheritedIdPropClass] { + o := MakeHttpExampleOrgInheritedIdPropClass() + return MakeObjectRef[HttpExampleOrgInheritedIdPropClass](o) +} + +func (self *HttpExampleOrgInheritedIdPropClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.HttpExampleOrgIdPropClassObject.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *HttpExampleOrgInheritedIdPropClassObject) Walk(path Path, visit Visit) { + self.HttpExampleOrgIdPropClassObject.Walk(path, visit) +} + + + +func (self *HttpExampleOrgInheritedIdPropClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.HttpExampleOrgIdPropClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// A class to test links +type HttpExampleOrgLinkClassObject struct { + SHACLObjectBase + + // A link to an extensible-class + extensible RefProperty[HttpExampleOrgExtensibleClass] + // A link-class list property + linkListProp RefListProperty[HttpExampleOrgLinkClass] + // A link-class property + linkProp RefProperty[HttpExampleOrgLinkClass] + // A link-class property with no sh:class + linkPropNoClass RefProperty[HttpExampleOrgLinkClass] +} + + +type HttpExampleOrgLinkClassObjectType struct { + SHACLTypeBase +} +var httpExampleOrgLinkClassType HttpExampleOrgLinkClassObjectType +var httpExampleOrgLinkClassExtensibleContext = map[string]string{} +var httpExampleOrgLinkClassLinkListPropContext = map[string]string{} +var httpExampleOrgLinkClassLinkPropContext = map[string]string{} +var httpExampleOrgLinkClassLinkPropNoClassContext = map[string]string{} + +func DecodeHttpExampleOrgLinkClass (data any, path Path, context map[string]string) (Ref[HttpExampleOrgLinkClass], error) { + return DecodeRef[HttpExampleOrgLinkClass](data, path, context, httpExampleOrgLinkClassType) +} + +func (self HttpExampleOrgLinkClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgLinkClass) + _ = obj + switch name { + case "http://example.org/link-class-extensible": + val, err := DecodeHttpExampleOrgExtensibleClass(value, path, httpExampleOrgLinkClassExtensibleContext) + if err != nil { + return false, err + } + err = obj.Extensible().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/link-class-link-list-prop": + val, err := DecodeList[Ref[HttpExampleOrgLinkClass]](value, path, httpExampleOrgLinkClassLinkListPropContext, DecodeHttpExampleOrgLinkClass) + if err != nil { + return false, err + } + err = obj.LinkListProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/link-class-link-prop": + val, err := DecodeHttpExampleOrgLinkClass(value, path, httpExampleOrgLinkClassLinkPropContext) + if err != nil { + return false, err + } + err = obj.LinkProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/link-class-link-prop-no-class": + val, err := DecodeHttpExampleOrgLinkClass(value, path, httpExampleOrgLinkClassLinkPropNoClassContext) + if err != nil { + return false, err + } + err = obj.LinkPropNoClass().Set(val) + if err != nil { + return false, err + } + return true, nil + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgLinkClassObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgLinkClassObject(&HttpExampleOrgLinkClassObject{}, self) +} + +func ConstructHttpExampleOrgLinkClassObject(o *HttpExampleOrgLinkClassObject, typ SHACLType) *HttpExampleOrgLinkClassObject { + ConstructSHACLObjectBase(&o.SHACLObjectBase, typ) + { + validators := []Validator[Ref[HttpExampleOrgExtensibleClass]]{} + o.extensible = NewRefProperty[HttpExampleOrgExtensibleClass]("extensible", validators) + } + { + validators := []Validator[Ref[HttpExampleOrgLinkClass]]{} + o.linkListProp = NewRefListProperty[HttpExampleOrgLinkClass]("linkListProp", validators) + } + { + validators := []Validator[Ref[HttpExampleOrgLinkClass]]{} + o.linkProp = NewRefProperty[HttpExampleOrgLinkClass]("linkProp", validators) + } + { + validators := []Validator[Ref[HttpExampleOrgLinkClass]]{} + o.linkPropNoClass = NewRefProperty[HttpExampleOrgLinkClass]("linkPropNoClass", validators) + } + return o +} + +type HttpExampleOrgLinkClass interface { + SHACLObject + Extensible() RefPropertyInterface[HttpExampleOrgExtensibleClass] + LinkListProp() ListPropertyInterface[Ref[HttpExampleOrgLinkClass]] + LinkProp() RefPropertyInterface[HttpExampleOrgLinkClass] + LinkPropNoClass() RefPropertyInterface[HttpExampleOrgLinkClass] +} + + +func MakeHttpExampleOrgLinkClass() HttpExampleOrgLinkClass { + return ConstructHttpExampleOrgLinkClassObject(&HttpExampleOrgLinkClassObject{}, httpExampleOrgLinkClassType) +} + +func MakeHttpExampleOrgLinkClassRef() Ref[HttpExampleOrgLinkClass] { + o := MakeHttpExampleOrgLinkClass() + return MakeObjectRef[HttpExampleOrgLinkClass](o) +} + +func (self *HttpExampleOrgLinkClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.SHACLObjectBase.Validate(path, handler) { + valid = false + } + { + prop_path := path.PushPath("extensible") + if ! self.extensible.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("linkListProp") + if ! self.linkListProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("linkProp") + if ! self.linkProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("linkPropNoClass") + if ! self.linkPropNoClass.Check(prop_path, handler) { + valid = false + } + } + return valid +} + +func (self *HttpExampleOrgLinkClassObject) Walk(path Path, visit Visit) { + self.SHACLObjectBase.Walk(path, visit) + self.extensible.Walk(path, visit) + self.linkListProp.Walk(path, visit) + self.linkProp.Walk(path, visit) + self.linkPropNoClass.Walk(path, visit) +} + + +func (self *HttpExampleOrgLinkClassObject) Extensible() RefPropertyInterface[HttpExampleOrgExtensibleClass] { return &self.extensible } +func (self *HttpExampleOrgLinkClassObject) LinkListProp() ListPropertyInterface[Ref[HttpExampleOrgLinkClass]] { return &self.linkListProp } +func (self *HttpExampleOrgLinkClassObject) LinkProp() RefPropertyInterface[HttpExampleOrgLinkClass] { return &self.linkProp } +func (self *HttpExampleOrgLinkClassObject) LinkPropNoClass() RefPropertyInterface[HttpExampleOrgLinkClass] { return &self.linkPropNoClass } + +func (self *HttpExampleOrgLinkClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.SHACLObjectBase.EncodeProperties(data, path, state); err != nil { + return err + } + if self.extensible.IsSet() { + val, err := EncodeRef[HttpExampleOrgExtensibleClass](self.extensible.Get(), path.PushPath("extensible"), httpExampleOrgLinkClassExtensibleContext, state) + if err != nil { + return err + } + data["http://example.org/link-class-extensible"] = val + } + if self.linkListProp.IsSet() { + val, err := EncodeList[Ref[HttpExampleOrgLinkClass]](self.linkListProp.Get(), path.PushPath("linkListProp"), httpExampleOrgLinkClassLinkListPropContext, state, EncodeRef[HttpExampleOrgLinkClass]) + if err != nil { + return err + } + data["http://example.org/link-class-link-list-prop"] = val + } + if self.linkProp.IsSet() { + val, err := EncodeRef[HttpExampleOrgLinkClass](self.linkProp.Get(), path.PushPath("linkProp"), httpExampleOrgLinkClassLinkPropContext, state) + if err != nil { + return err + } + data["http://example.org/link-class-link-prop"] = val + } + if self.linkPropNoClass.IsSet() { + val, err := EncodeRef[HttpExampleOrgLinkClass](self.linkPropNoClass.Get(), path.PushPath("linkPropNoClass"), httpExampleOrgLinkClassLinkPropNoClassContext, state) + if err != nil { + return err + } + data["http://example.org/link-class-link-prop-no-class"] = val + } + return nil +} + +// A class derived from link-class +type HttpExampleOrgLinkDerivedClassObject struct { + HttpExampleOrgLinkClassObject + +} + + +type HttpExampleOrgLinkDerivedClassObjectType struct { + SHACLTypeBase +} +var httpExampleOrgLinkDerivedClassType HttpExampleOrgLinkDerivedClassObjectType + +func DecodeHttpExampleOrgLinkDerivedClass (data any, path Path, context map[string]string) (Ref[HttpExampleOrgLinkDerivedClass], error) { + return DecodeRef[HttpExampleOrgLinkDerivedClass](data, path, context, httpExampleOrgLinkDerivedClassType) +} + +func (self HttpExampleOrgLinkDerivedClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgLinkDerivedClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgLinkDerivedClassObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgLinkDerivedClassObject(&HttpExampleOrgLinkDerivedClassObject{}, self) +} + +func ConstructHttpExampleOrgLinkDerivedClassObject(o *HttpExampleOrgLinkDerivedClassObject, typ SHACLType) *HttpExampleOrgLinkDerivedClassObject { + ConstructHttpExampleOrgLinkClassObject(&o.HttpExampleOrgLinkClassObject, typ) + return o +} + +type HttpExampleOrgLinkDerivedClass interface { + HttpExampleOrgLinkClass +} + + +func MakeHttpExampleOrgLinkDerivedClass() HttpExampleOrgLinkDerivedClass { + return ConstructHttpExampleOrgLinkDerivedClassObject(&HttpExampleOrgLinkDerivedClassObject{}, httpExampleOrgLinkDerivedClassType) +} + +func MakeHttpExampleOrgLinkDerivedClassRef() Ref[HttpExampleOrgLinkDerivedClass] { + o := MakeHttpExampleOrgLinkDerivedClass() + return MakeObjectRef[HttpExampleOrgLinkDerivedClass](o) +} + +func (self *HttpExampleOrgLinkDerivedClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.HttpExampleOrgLinkClassObject.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *HttpExampleOrgLinkDerivedClassObject) Walk(path Path, visit Visit) { + self.HttpExampleOrgLinkClassObject.Walk(path, visit) +} + + + +func (self *HttpExampleOrgLinkDerivedClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.HttpExampleOrgLinkClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// A class that must be a blank node +type HttpExampleOrgNodeKindBlankObject struct { + HttpExampleOrgLinkClassObject + +} + + +type HttpExampleOrgNodeKindBlankObjectType struct { + SHACLTypeBase +} +var httpExampleOrgNodeKindBlankType HttpExampleOrgNodeKindBlankObjectType + +func DecodeHttpExampleOrgNodeKindBlank (data any, path Path, context map[string]string) (Ref[HttpExampleOrgNodeKindBlank], error) { + return DecodeRef[HttpExampleOrgNodeKindBlank](data, path, context, httpExampleOrgNodeKindBlankType) +} + +func (self HttpExampleOrgNodeKindBlankObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgNodeKindBlank) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgNodeKindBlankObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgNodeKindBlankObject(&HttpExampleOrgNodeKindBlankObject{}, self) +} + +func ConstructHttpExampleOrgNodeKindBlankObject(o *HttpExampleOrgNodeKindBlankObject, typ SHACLType) *HttpExampleOrgNodeKindBlankObject { + ConstructHttpExampleOrgLinkClassObject(&o.HttpExampleOrgLinkClassObject, typ) + return o +} + +type HttpExampleOrgNodeKindBlank interface { + HttpExampleOrgLinkClass +} + + +func MakeHttpExampleOrgNodeKindBlank() HttpExampleOrgNodeKindBlank { + return ConstructHttpExampleOrgNodeKindBlankObject(&HttpExampleOrgNodeKindBlankObject{}, httpExampleOrgNodeKindBlankType) +} + +func MakeHttpExampleOrgNodeKindBlankRef() Ref[HttpExampleOrgNodeKindBlank] { + o := MakeHttpExampleOrgNodeKindBlank() + return MakeObjectRef[HttpExampleOrgNodeKindBlank](o) +} + +func (self *HttpExampleOrgNodeKindBlankObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.HttpExampleOrgLinkClassObject.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *HttpExampleOrgNodeKindBlankObject) Walk(path Path, visit Visit) { + self.HttpExampleOrgLinkClassObject.Walk(path, visit) +} + + + +func (self *HttpExampleOrgNodeKindBlankObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.HttpExampleOrgLinkClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// A class that must be an IRI +type HttpExampleOrgNodeKindIriObject struct { + HttpExampleOrgLinkClassObject + +} + + +type HttpExampleOrgNodeKindIriObjectType struct { + SHACLTypeBase +} +var httpExampleOrgNodeKindIriType HttpExampleOrgNodeKindIriObjectType + +func DecodeHttpExampleOrgNodeKindIri (data any, path Path, context map[string]string) (Ref[HttpExampleOrgNodeKindIri], error) { + return DecodeRef[HttpExampleOrgNodeKindIri](data, path, context, httpExampleOrgNodeKindIriType) +} + +func (self HttpExampleOrgNodeKindIriObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgNodeKindIri) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgNodeKindIriObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgNodeKindIriObject(&HttpExampleOrgNodeKindIriObject{}, self) +} + +func ConstructHttpExampleOrgNodeKindIriObject(o *HttpExampleOrgNodeKindIriObject, typ SHACLType) *HttpExampleOrgNodeKindIriObject { + ConstructHttpExampleOrgLinkClassObject(&o.HttpExampleOrgLinkClassObject, typ) + return o +} + +type HttpExampleOrgNodeKindIri interface { + HttpExampleOrgLinkClass +} + + +func MakeHttpExampleOrgNodeKindIri() HttpExampleOrgNodeKindIri { + return ConstructHttpExampleOrgNodeKindIriObject(&HttpExampleOrgNodeKindIriObject{}, httpExampleOrgNodeKindIriType) +} + +func MakeHttpExampleOrgNodeKindIriRef() Ref[HttpExampleOrgNodeKindIri] { + o := MakeHttpExampleOrgNodeKindIri() + return MakeObjectRef[HttpExampleOrgNodeKindIri](o) +} + +func (self *HttpExampleOrgNodeKindIriObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.HttpExampleOrgLinkClassObject.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *HttpExampleOrgNodeKindIriObject) Walk(path Path, visit Visit) { + self.HttpExampleOrgLinkClassObject.Walk(path, visit) +} + + + +func (self *HttpExampleOrgNodeKindIriObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.HttpExampleOrgLinkClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// A class that can be either a blank node or an IRI +type HttpExampleOrgNodeKindIriOrBlankObject struct { + HttpExampleOrgLinkClassObject + +} + + +type HttpExampleOrgNodeKindIriOrBlankObjectType struct { + SHACLTypeBase +} +var httpExampleOrgNodeKindIriOrBlankType HttpExampleOrgNodeKindIriOrBlankObjectType + +func DecodeHttpExampleOrgNodeKindIriOrBlank (data any, path Path, context map[string]string) (Ref[HttpExampleOrgNodeKindIriOrBlank], error) { + return DecodeRef[HttpExampleOrgNodeKindIriOrBlank](data, path, context, httpExampleOrgNodeKindIriOrBlankType) +} + +func (self HttpExampleOrgNodeKindIriOrBlankObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgNodeKindIriOrBlank) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgNodeKindIriOrBlankObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgNodeKindIriOrBlankObject(&HttpExampleOrgNodeKindIriOrBlankObject{}, self) +} + +func ConstructHttpExampleOrgNodeKindIriOrBlankObject(o *HttpExampleOrgNodeKindIriOrBlankObject, typ SHACLType) *HttpExampleOrgNodeKindIriOrBlankObject { + ConstructHttpExampleOrgLinkClassObject(&o.HttpExampleOrgLinkClassObject, typ) + return o +} + +type HttpExampleOrgNodeKindIriOrBlank interface { + HttpExampleOrgLinkClass +} + + +func MakeHttpExampleOrgNodeKindIriOrBlank() HttpExampleOrgNodeKindIriOrBlank { + return ConstructHttpExampleOrgNodeKindIriOrBlankObject(&HttpExampleOrgNodeKindIriOrBlankObject{}, httpExampleOrgNodeKindIriOrBlankType) +} + +func MakeHttpExampleOrgNodeKindIriOrBlankRef() Ref[HttpExampleOrgNodeKindIriOrBlank] { + o := MakeHttpExampleOrgNodeKindIriOrBlank() + return MakeObjectRef[HttpExampleOrgNodeKindIriOrBlank](o) +} + +func (self *HttpExampleOrgNodeKindIriOrBlankObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.HttpExampleOrgLinkClassObject.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *HttpExampleOrgNodeKindIriOrBlankObject) Walk(path Path, visit Visit) { + self.HttpExampleOrgLinkClassObject.Walk(path, visit) +} + + + +func (self *HttpExampleOrgNodeKindIriOrBlankObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.HttpExampleOrgLinkClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// A class that is not a nodeshape +type HttpExampleOrgNonShapeClassObject struct { + SHACLObjectBase + +} + + +type HttpExampleOrgNonShapeClassObjectType struct { + SHACLTypeBase +} +var httpExampleOrgNonShapeClassType HttpExampleOrgNonShapeClassObjectType + +func DecodeHttpExampleOrgNonShapeClass (data any, path Path, context map[string]string) (Ref[HttpExampleOrgNonShapeClass], error) { + return DecodeRef[HttpExampleOrgNonShapeClass](data, path, context, httpExampleOrgNonShapeClassType) +} + +func (self HttpExampleOrgNonShapeClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgNonShapeClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgNonShapeClassObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgNonShapeClassObject(&HttpExampleOrgNonShapeClassObject{}, self) +} + +func ConstructHttpExampleOrgNonShapeClassObject(o *HttpExampleOrgNonShapeClassObject, typ SHACLType) *HttpExampleOrgNonShapeClassObject { + ConstructSHACLObjectBase(&o.SHACLObjectBase, typ) + return o +} + +type HttpExampleOrgNonShapeClass interface { + SHACLObject +} + + +func MakeHttpExampleOrgNonShapeClass() HttpExampleOrgNonShapeClass { + return ConstructHttpExampleOrgNonShapeClassObject(&HttpExampleOrgNonShapeClassObject{}, httpExampleOrgNonShapeClassType) +} + +func MakeHttpExampleOrgNonShapeClassRef() Ref[HttpExampleOrgNonShapeClass] { + o := MakeHttpExampleOrgNonShapeClass() + return MakeObjectRef[HttpExampleOrgNonShapeClass](o) +} + +func (self *HttpExampleOrgNonShapeClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.SHACLObjectBase.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *HttpExampleOrgNonShapeClassObject) Walk(path Path, visit Visit) { + self.SHACLObjectBase.Walk(path, visit) +} + + + +func (self *HttpExampleOrgNonShapeClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.SHACLObjectBase.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// The parent class +type HttpExampleOrgParentClassObject struct { + SHACLObjectBase + +} + + +type HttpExampleOrgParentClassObjectType struct { + SHACLTypeBase +} +var httpExampleOrgParentClassType HttpExampleOrgParentClassObjectType + +func DecodeHttpExampleOrgParentClass (data any, path Path, context map[string]string) (Ref[HttpExampleOrgParentClass], error) { + return DecodeRef[HttpExampleOrgParentClass](data, path, context, httpExampleOrgParentClassType) +} + +func (self HttpExampleOrgParentClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgParentClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgParentClassObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgParentClassObject(&HttpExampleOrgParentClassObject{}, self) +} + +func ConstructHttpExampleOrgParentClassObject(o *HttpExampleOrgParentClassObject, typ SHACLType) *HttpExampleOrgParentClassObject { + ConstructSHACLObjectBase(&o.SHACLObjectBase, typ) + return o +} + +type HttpExampleOrgParentClass interface { + SHACLObject +} + + +func MakeHttpExampleOrgParentClass() HttpExampleOrgParentClass { + return ConstructHttpExampleOrgParentClassObject(&HttpExampleOrgParentClassObject{}, httpExampleOrgParentClassType) +} + +func MakeHttpExampleOrgParentClassRef() Ref[HttpExampleOrgParentClass] { + o := MakeHttpExampleOrgParentClass() + return MakeObjectRef[HttpExampleOrgParentClass](o) +} + +func (self *HttpExampleOrgParentClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.SHACLObjectBase.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *HttpExampleOrgParentClassObject) Walk(path Path, visit Visit) { + self.SHACLObjectBase.Walk(path, visit) +} + + + +func (self *HttpExampleOrgParentClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.SHACLObjectBase.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// A class with a mandatory abstract class +type HttpExampleOrgRequiredAbstractObject struct { + SHACLObjectBase + + // A required abstract class property + abstractClassProp RefProperty[HttpExampleOrgAbstractClass] +} + + +type HttpExampleOrgRequiredAbstractObjectType struct { + SHACLTypeBase +} +var httpExampleOrgRequiredAbstractType HttpExampleOrgRequiredAbstractObjectType +var httpExampleOrgRequiredAbstractAbstractClassPropContext = map[string]string{} + +func DecodeHttpExampleOrgRequiredAbstract (data any, path Path, context map[string]string) (Ref[HttpExampleOrgRequiredAbstract], error) { + return DecodeRef[HttpExampleOrgRequiredAbstract](data, path, context, httpExampleOrgRequiredAbstractType) +} + +func (self HttpExampleOrgRequiredAbstractObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgRequiredAbstract) + _ = obj + switch name { + case "http://example.org/required-abstract/abstract-class-prop": + val, err := DecodeHttpExampleOrgAbstractClass(value, path, httpExampleOrgRequiredAbstractAbstractClassPropContext) + if err != nil { + return false, err + } + err = obj.AbstractClassProp().Set(val) + if err != nil { + return false, err + } + return true, nil + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgRequiredAbstractObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgRequiredAbstractObject(&HttpExampleOrgRequiredAbstractObject{}, self) +} + +func ConstructHttpExampleOrgRequiredAbstractObject(o *HttpExampleOrgRequiredAbstractObject, typ SHACLType) *HttpExampleOrgRequiredAbstractObject { + ConstructSHACLObjectBase(&o.SHACLObjectBase, typ) + { + validators := []Validator[Ref[HttpExampleOrgAbstractClass]]{} + o.abstractClassProp = NewRefProperty[HttpExampleOrgAbstractClass]("abstractClassProp", validators) + } + return o +} + +type HttpExampleOrgRequiredAbstract interface { + SHACLObject + AbstractClassProp() RefPropertyInterface[HttpExampleOrgAbstractClass] +} + + +func MakeHttpExampleOrgRequiredAbstract() HttpExampleOrgRequiredAbstract { + return ConstructHttpExampleOrgRequiredAbstractObject(&HttpExampleOrgRequiredAbstractObject{}, httpExampleOrgRequiredAbstractType) +} + +func MakeHttpExampleOrgRequiredAbstractRef() Ref[HttpExampleOrgRequiredAbstract] { + o := MakeHttpExampleOrgRequiredAbstract() + return MakeObjectRef[HttpExampleOrgRequiredAbstract](o) +} + +func (self *HttpExampleOrgRequiredAbstractObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.SHACLObjectBase.Validate(path, handler) { + valid = false + } + { + prop_path := path.PushPath("abstractClassProp") + if ! self.abstractClassProp.Check(prop_path, handler) { + valid = false + } + if ! self.abstractClassProp.IsSet() { + if handler != nil { + handler.HandleError(&ValidationError{"abstractClassProp", "Value is required"}, prop_path) + } + valid = false + } + } + return valid +} + +func (self *HttpExampleOrgRequiredAbstractObject) Walk(path Path, visit Visit) { + self.SHACLObjectBase.Walk(path, visit) + self.abstractClassProp.Walk(path, visit) +} + + +func (self *HttpExampleOrgRequiredAbstractObject) AbstractClassProp() RefPropertyInterface[HttpExampleOrgAbstractClass] { return &self.abstractClassProp } + +func (self *HttpExampleOrgRequiredAbstractObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.SHACLObjectBase.EncodeProperties(data, path, state); err != nil { + return err + } + if self.abstractClassProp.IsSet() { + val, err := EncodeRef[HttpExampleOrgAbstractClass](self.abstractClassProp.Get(), path.PushPath("abstractClassProp"), httpExampleOrgRequiredAbstractAbstractClassPropContext, state) + if err != nil { + return err + } + data["http://example.org/required-abstract/abstract-class-prop"] = val + } + return nil +} + +// Another class +type HttpExampleOrgTestAnotherClassObject struct { + SHACLObjectBase + +} + + +type HttpExampleOrgTestAnotherClassObjectType struct { + SHACLTypeBase +} +var httpExampleOrgTestAnotherClassType HttpExampleOrgTestAnotherClassObjectType + +func DecodeHttpExampleOrgTestAnotherClass (data any, path Path, context map[string]string) (Ref[HttpExampleOrgTestAnotherClass], error) { + return DecodeRef[HttpExampleOrgTestAnotherClass](data, path, context, httpExampleOrgTestAnotherClassType) +} + +func (self HttpExampleOrgTestAnotherClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgTestAnotherClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgTestAnotherClassObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgTestAnotherClassObject(&HttpExampleOrgTestAnotherClassObject{}, self) +} + +func ConstructHttpExampleOrgTestAnotherClassObject(o *HttpExampleOrgTestAnotherClassObject, typ SHACLType) *HttpExampleOrgTestAnotherClassObject { + ConstructSHACLObjectBase(&o.SHACLObjectBase, typ) + return o +} + +type HttpExampleOrgTestAnotherClass interface { + SHACLObject +} + + +func MakeHttpExampleOrgTestAnotherClass() HttpExampleOrgTestAnotherClass { + return ConstructHttpExampleOrgTestAnotherClassObject(&HttpExampleOrgTestAnotherClassObject{}, httpExampleOrgTestAnotherClassType) +} + +func MakeHttpExampleOrgTestAnotherClassRef() Ref[HttpExampleOrgTestAnotherClass] { + o := MakeHttpExampleOrgTestAnotherClass() + return MakeObjectRef[HttpExampleOrgTestAnotherClass](o) +} + +func (self *HttpExampleOrgTestAnotherClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.SHACLObjectBase.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *HttpExampleOrgTestAnotherClassObject) Walk(path Path, visit Visit) { + self.SHACLObjectBase.Walk(path, visit) +} + + + +func (self *HttpExampleOrgTestAnotherClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.SHACLObjectBase.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// The test class +type HttpExampleOrgTestClassObject struct { + HttpExampleOrgParentClassObject + + // A property that conflicts with an existing SHACLObject property + encode Property[string] + // A property that is a keyword + import_ Property[string] + // a URI + anyuriProp Property[string] + // a boolean property + booleanProp Property[bool] + // A test-class list property + classListProp RefListProperty[HttpExampleOrgTestClass] + // A test-class property + classProp RefProperty[HttpExampleOrgTestClass] + // A test-class property with no sh:class + classPropNoClass RefProperty[HttpExampleOrgTestClass] + // A datetime list property + datetimeListProp ListProperty[time.Time] + // A scalar datetime property + datetimeScalarProp Property[time.Time] + // A scalar dateTimeStamp property + datetimestampScalarProp Property[time.Time] + // A enum list property + enumListProp ListProperty[string] + // A enum property + enumProp Property[string] + // A enum property with no sh:class + enumPropNoClass Property[string] + // a float property + floatProp Property[float64] + // a non-negative integer + integerProp Property[int] + // A named property + namedProperty Property[string] + // A class with no shape + nonShape RefProperty[HttpExampleOrgNonShapeClass] + // a non-negative integer + nonnegativeIntegerProp Property[int] + // A positive integer + positiveIntegerProp Property[int] + // A regex validated string + regex Property[string] + // A regex dateTime + regexDatetime Property[time.Time] + // A regex dateTimeStamp + regexDatetimestamp Property[time.Time] + // A regex validated string list + regexList ListProperty[string] + // A string list property with no sh:datatype + stringListNoDatatype ListProperty[string] + // A string list property + stringListProp ListProperty[string] + // A scalar string propery + stringScalarProp Property[string] +} +const HttpExampleOrgTestClassNamed = "http://example.org/test-class/named" + +type HttpExampleOrgTestClassObjectType struct { + SHACLTypeBase +} +var httpExampleOrgTestClassType HttpExampleOrgTestClassObjectType +var httpExampleOrgTestClassEncodeContext = map[string]string{} +var httpExampleOrgTestClassImportContext = map[string]string{} +var httpExampleOrgTestClassAnyuriPropContext = map[string]string{} +var httpExampleOrgTestClassBooleanPropContext = map[string]string{} +var httpExampleOrgTestClassClassListPropContext = map[string]string{} +var httpExampleOrgTestClassClassPropContext = map[string]string{} +var httpExampleOrgTestClassClassPropNoClassContext = map[string]string{} +var httpExampleOrgTestClassDatetimeListPropContext = map[string]string{} +var httpExampleOrgTestClassDatetimeScalarPropContext = map[string]string{} +var httpExampleOrgTestClassDatetimestampScalarPropContext = map[string]string{} +var httpExampleOrgTestClassEnumListPropContext = map[string]string{ + "http://example.org/enumType/bar": "http://example.org/enumType/bar", + "http://example.org/enumType/foo": "http://example.org/enumType/foo", + "http://example.org/enumType/nolabel": "http://example.org/enumType/nolabel", + "http://example.org/enumType/non-named-individual": "http://example.org/enumType/non-named-individual",} +var httpExampleOrgTestClassEnumPropContext = map[string]string{ + "http://example.org/enumType/bar": "http://example.org/enumType/bar", + "http://example.org/enumType/foo": "http://example.org/enumType/foo", + "http://example.org/enumType/nolabel": "http://example.org/enumType/nolabel", + "http://example.org/enumType/non-named-individual": "http://example.org/enumType/non-named-individual",} +var httpExampleOrgTestClassEnumPropNoClassContext = map[string]string{ + "http://example.org/enumType/bar": "http://example.org/enumType/bar", + "http://example.org/enumType/foo": "http://example.org/enumType/foo", + "http://example.org/enumType/nolabel": "http://example.org/enumType/nolabel", + "http://example.org/enumType/non-named-individual": "http://example.org/enumType/non-named-individual",} +var httpExampleOrgTestClassFloatPropContext = map[string]string{} +var httpExampleOrgTestClassIntegerPropContext = map[string]string{} +var httpExampleOrgTestClassNamedPropertyContext = map[string]string{} +var httpExampleOrgTestClassNonShapeContext = map[string]string{} +var httpExampleOrgTestClassNonnegativeIntegerPropContext = map[string]string{} +var httpExampleOrgTestClassPositiveIntegerPropContext = map[string]string{} +var httpExampleOrgTestClassRegexContext = map[string]string{} +var httpExampleOrgTestClassRegexDatetimeContext = map[string]string{} +var httpExampleOrgTestClassRegexDatetimestampContext = map[string]string{} +var httpExampleOrgTestClassRegexListContext = map[string]string{} +var httpExampleOrgTestClassStringListNoDatatypeContext = map[string]string{} +var httpExampleOrgTestClassStringListPropContext = map[string]string{} +var httpExampleOrgTestClassStringScalarPropContext = map[string]string{} + +func DecodeHttpExampleOrgTestClass (data any, path Path, context map[string]string) (Ref[HttpExampleOrgTestClass], error) { + return DecodeRef[HttpExampleOrgTestClass](data, path, context, httpExampleOrgTestClassType) +} + +func (self HttpExampleOrgTestClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgTestClass) + _ = obj + switch name { + case "http://example.org/encode": + val, err := DecodeString(value, path, httpExampleOrgTestClassEncodeContext) + if err != nil { + return false, err + } + err = obj.Encode().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/import": + val, err := DecodeString(value, path, httpExampleOrgTestClassImportContext) + if err != nil { + return false, err + } + err = obj.Import().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/anyuri-prop": + val, err := DecodeString(value, path, httpExampleOrgTestClassAnyuriPropContext) + if err != nil { + return false, err + } + err = obj.AnyuriProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/boolean-prop": + val, err := DecodeBoolean(value, path, httpExampleOrgTestClassBooleanPropContext) + if err != nil { + return false, err + } + err = obj.BooleanProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/class-list-prop": + val, err := DecodeList[Ref[HttpExampleOrgTestClass]](value, path, httpExampleOrgTestClassClassListPropContext, DecodeHttpExampleOrgTestClass) + if err != nil { + return false, err + } + err = obj.ClassListProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/class-prop": + val, err := DecodeHttpExampleOrgTestClass(value, path, httpExampleOrgTestClassClassPropContext) + if err != nil { + return false, err + } + err = obj.ClassProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/class-prop-no-class": + val, err := DecodeHttpExampleOrgTestClass(value, path, httpExampleOrgTestClassClassPropNoClassContext) + if err != nil { + return false, err + } + err = obj.ClassPropNoClass().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/datetime-list-prop": + val, err := DecodeList[time.Time](value, path, httpExampleOrgTestClassDatetimeListPropContext, DecodeDateTime) + if err != nil { + return false, err + } + err = obj.DatetimeListProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/datetime-scalar-prop": + val, err := DecodeDateTime(value, path, httpExampleOrgTestClassDatetimeScalarPropContext) + if err != nil { + return false, err + } + err = obj.DatetimeScalarProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/datetimestamp-scalar-prop": + val, err := DecodeDateTimeStamp(value, path, httpExampleOrgTestClassDatetimestampScalarPropContext) + if err != nil { + return false, err + } + err = obj.DatetimestampScalarProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/enum-list-prop": + val, err := DecodeList[string](value, path, httpExampleOrgTestClassEnumListPropContext, DecodeIRI) + if err != nil { + return false, err + } + err = obj.EnumListProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/enum-prop": + val, err := DecodeIRI(value, path, httpExampleOrgTestClassEnumPropContext) + if err != nil { + return false, err + } + err = obj.EnumProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/enum-prop-no-class": + val, err := DecodeIRI(value, path, httpExampleOrgTestClassEnumPropNoClassContext) + if err != nil { + return false, err + } + err = obj.EnumPropNoClass().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/float-prop": + val, err := DecodeFloat(value, path, httpExampleOrgTestClassFloatPropContext) + if err != nil { + return false, err + } + err = obj.FloatProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/integer-prop": + val, err := DecodeInteger(value, path, httpExampleOrgTestClassIntegerPropContext) + if err != nil { + return false, err + } + err = obj.IntegerProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/named-property": + val, err := DecodeString(value, path, httpExampleOrgTestClassNamedPropertyContext) + if err != nil { + return false, err + } + err = obj.NamedProperty().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/non-shape": + val, err := DecodeHttpExampleOrgNonShapeClass(value, path, httpExampleOrgTestClassNonShapeContext) + if err != nil { + return false, err + } + err = obj.NonShape().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/nonnegative-integer-prop": + val, err := DecodeInteger(value, path, httpExampleOrgTestClassNonnegativeIntegerPropContext) + if err != nil { + return false, err + } + err = obj.NonnegativeIntegerProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/positive-integer-prop": + val, err := DecodeInteger(value, path, httpExampleOrgTestClassPositiveIntegerPropContext) + if err != nil { + return false, err + } + err = obj.PositiveIntegerProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/regex": + val, err := DecodeString(value, path, httpExampleOrgTestClassRegexContext) + if err != nil { + return false, err + } + err = obj.Regex().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/regex-datetime": + val, err := DecodeDateTime(value, path, httpExampleOrgTestClassRegexDatetimeContext) + if err != nil { + return false, err + } + err = obj.RegexDatetime().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/regex-datetimestamp": + val, err := DecodeDateTimeStamp(value, path, httpExampleOrgTestClassRegexDatetimestampContext) + if err != nil { + return false, err + } + err = obj.RegexDatetimestamp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/regex-list": + val, err := DecodeList[string](value, path, httpExampleOrgTestClassRegexListContext, DecodeString) + if err != nil { + return false, err + } + err = obj.RegexList().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/string-list-no-datatype": + val, err := DecodeList[string](value, path, httpExampleOrgTestClassStringListNoDatatypeContext, DecodeString) + if err != nil { + return false, err + } + err = obj.StringListNoDatatype().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/string-list-prop": + val, err := DecodeList[string](value, path, httpExampleOrgTestClassStringListPropContext, DecodeString) + if err != nil { + return false, err + } + err = obj.StringListProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/string-scalar-prop": + val, err := DecodeString(value, path, httpExampleOrgTestClassStringScalarPropContext) + if err != nil { + return false, err + } + err = obj.StringScalarProp().Set(val) + if err != nil { + return false, err + } + return true, nil + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgTestClassObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgTestClassObject(&HttpExampleOrgTestClassObject{}, self) +} + +func ConstructHttpExampleOrgTestClassObject(o *HttpExampleOrgTestClassObject, typ SHACLType) *HttpExampleOrgTestClassObject { + ConstructHttpExampleOrgParentClassObject(&o.HttpExampleOrgParentClassObject, typ) + { + validators := []Validator[string]{} + o.encode = NewProperty[string]("encode", validators) + } + { + validators := []Validator[string]{} + o.import_ = NewProperty[string]("import_", validators) + } + { + validators := []Validator[string]{} + o.anyuriProp = NewProperty[string]("anyuriProp", validators) + } + { + validators := []Validator[bool]{} + o.booleanProp = NewProperty[bool]("booleanProp", validators) + } + { + validators := []Validator[Ref[HttpExampleOrgTestClass]]{} + o.classListProp = NewRefListProperty[HttpExampleOrgTestClass]("classListProp", validators) + } + { + validators := []Validator[Ref[HttpExampleOrgTestClass]]{} + o.classProp = NewRefProperty[HttpExampleOrgTestClass]("classProp", validators) + } + { + validators := []Validator[Ref[HttpExampleOrgTestClass]]{} + o.classPropNoClass = NewRefProperty[HttpExampleOrgTestClass]("classPropNoClass", validators) + } + { + validators := []Validator[time.Time]{} + o.datetimeListProp = NewListProperty[time.Time]("datetimeListProp", validators) + } + { + validators := []Validator[time.Time]{} + o.datetimeScalarProp = NewProperty[time.Time]("datetimeScalarProp", validators) + } + { + validators := []Validator[time.Time]{} + o.datetimestampScalarProp = NewProperty[time.Time]("datetimestampScalarProp", validators) + } + { + validators := []Validator[string]{} + validators = append(validators, + EnumValidator{[]string{ + "http://example.org/enumType/bar", + "http://example.org/enumType/foo", + "http://example.org/enumType/nolabel", + "http://example.org/enumType/non-named-individual", + }}) + o.enumListProp = NewListProperty[string]("enumListProp", validators) + } + { + validators := []Validator[string]{} + validators = append(validators, + EnumValidator{[]string{ + "http://example.org/enumType/bar", + "http://example.org/enumType/foo", + "http://example.org/enumType/nolabel", + "http://example.org/enumType/non-named-individual", + }}) + o.enumProp = NewProperty[string]("enumProp", validators) + } + { + validators := []Validator[string]{} + validators = append(validators, + EnumValidator{[]string{ + "http://example.org/enumType/bar", + "http://example.org/enumType/foo", + "http://example.org/enumType/nolabel", + "http://example.org/enumType/non-named-individual", + }}) + o.enumPropNoClass = NewProperty[string]("enumPropNoClass", validators) + } + { + validators := []Validator[float64]{} + o.floatProp = NewProperty[float64]("floatProp", validators) + } + { + validators := []Validator[int]{} + o.integerProp = NewProperty[int]("integerProp", validators) + } + { + validators := []Validator[string]{} + o.namedProperty = NewProperty[string]("namedProperty", validators) + } + { + validators := []Validator[Ref[HttpExampleOrgNonShapeClass]]{} + o.nonShape = NewRefProperty[HttpExampleOrgNonShapeClass]("nonShape", validators) + } + { + validators := []Validator[int]{} + validators = append(validators, IntegerMinValidator{0}) + o.nonnegativeIntegerProp = NewProperty[int]("nonnegativeIntegerProp", validators) + } + { + validators := []Validator[int]{} + validators = append(validators, IntegerMinValidator{1}) + o.positiveIntegerProp = NewProperty[int]("positiveIntegerProp", validators) + } + { + validators := []Validator[string]{} + validators = append(validators, RegexValidator[string]{`^foo\d`}) + o.regex = NewProperty[string]("regex", validators) + } + { + validators := []Validator[time.Time]{} + validators = append(validators, RegexValidator[time.Time]{`^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d\+01:00$`}) + o.regexDatetime = NewProperty[time.Time]("regexDatetime", validators) + } + { + validators := []Validator[time.Time]{} + validators = append(validators, RegexValidator[time.Time]{`^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\dZ$`}) + o.regexDatetimestamp = NewProperty[time.Time]("regexDatetimestamp", validators) + } + { + validators := []Validator[string]{} + validators = append(validators, RegexValidator[string]{`^foo\d`}) + o.regexList = NewListProperty[string]("regexList", validators) + } + { + validators := []Validator[string]{} + o.stringListNoDatatype = NewListProperty[string]("stringListNoDatatype", validators) + } + { + validators := []Validator[string]{} + o.stringListProp = NewListProperty[string]("stringListProp", validators) + } + { + validators := []Validator[string]{} + o.stringScalarProp = NewProperty[string]("stringScalarProp", validators) + } + return o +} + +type HttpExampleOrgTestClass interface { + HttpExampleOrgParentClass + Encode() PropertyInterface[string] + Import() PropertyInterface[string] + AnyuriProp() PropertyInterface[string] + BooleanProp() PropertyInterface[bool] + ClassListProp() ListPropertyInterface[Ref[HttpExampleOrgTestClass]] + ClassProp() RefPropertyInterface[HttpExampleOrgTestClass] + ClassPropNoClass() RefPropertyInterface[HttpExampleOrgTestClass] + DatetimeListProp() ListPropertyInterface[time.Time] + DatetimeScalarProp() PropertyInterface[time.Time] + DatetimestampScalarProp() PropertyInterface[time.Time] + EnumListProp() ListPropertyInterface[string] + EnumProp() PropertyInterface[string] + EnumPropNoClass() PropertyInterface[string] + FloatProp() PropertyInterface[float64] + IntegerProp() PropertyInterface[int] + NamedProperty() PropertyInterface[string] + NonShape() RefPropertyInterface[HttpExampleOrgNonShapeClass] + NonnegativeIntegerProp() PropertyInterface[int] + PositiveIntegerProp() PropertyInterface[int] + Regex() PropertyInterface[string] + RegexDatetime() PropertyInterface[time.Time] + RegexDatetimestamp() PropertyInterface[time.Time] + RegexList() ListPropertyInterface[string] + StringListNoDatatype() ListPropertyInterface[string] + StringListProp() ListPropertyInterface[string] + StringScalarProp() PropertyInterface[string] +} + + +func MakeHttpExampleOrgTestClass() HttpExampleOrgTestClass { + return ConstructHttpExampleOrgTestClassObject(&HttpExampleOrgTestClassObject{}, httpExampleOrgTestClassType) +} + +func MakeHttpExampleOrgTestClassRef() Ref[HttpExampleOrgTestClass] { + o := MakeHttpExampleOrgTestClass() + return MakeObjectRef[HttpExampleOrgTestClass](o) +} + +func (self *HttpExampleOrgTestClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.HttpExampleOrgParentClassObject.Validate(path, handler) { + valid = false + } + { + prop_path := path.PushPath("encode") + if ! self.encode.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("import_") + if ! self.import_.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("anyuriProp") + if ! self.anyuriProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("booleanProp") + if ! self.booleanProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("classListProp") + if ! self.classListProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("classProp") + if ! self.classProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("classPropNoClass") + if ! self.classPropNoClass.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("datetimeListProp") + if ! self.datetimeListProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("datetimeScalarProp") + if ! self.datetimeScalarProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("datetimestampScalarProp") + if ! self.datetimestampScalarProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("enumListProp") + if ! self.enumListProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("enumProp") + if ! self.enumProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("enumPropNoClass") + if ! self.enumPropNoClass.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("floatProp") + if ! self.floatProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("integerProp") + if ! self.integerProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("namedProperty") + if ! self.namedProperty.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("nonShape") + if ! self.nonShape.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("nonnegativeIntegerProp") + if ! self.nonnegativeIntegerProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("positiveIntegerProp") + if ! self.positiveIntegerProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("regex") + if ! self.regex.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("regexDatetime") + if ! self.regexDatetime.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("regexDatetimestamp") + if ! self.regexDatetimestamp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("regexList") + if ! self.regexList.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("stringListNoDatatype") + if ! self.stringListNoDatatype.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("stringListProp") + if ! self.stringListProp.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("stringScalarProp") + if ! self.stringScalarProp.Check(prop_path, handler) { + valid = false + } + } + return valid +} + +func (self *HttpExampleOrgTestClassObject) Walk(path Path, visit Visit) { + self.HttpExampleOrgParentClassObject.Walk(path, visit) + self.encode.Walk(path, visit) + self.import_.Walk(path, visit) + self.anyuriProp.Walk(path, visit) + self.booleanProp.Walk(path, visit) + self.classListProp.Walk(path, visit) + self.classProp.Walk(path, visit) + self.classPropNoClass.Walk(path, visit) + self.datetimeListProp.Walk(path, visit) + self.datetimeScalarProp.Walk(path, visit) + self.datetimestampScalarProp.Walk(path, visit) + self.enumListProp.Walk(path, visit) + self.enumProp.Walk(path, visit) + self.enumPropNoClass.Walk(path, visit) + self.floatProp.Walk(path, visit) + self.integerProp.Walk(path, visit) + self.namedProperty.Walk(path, visit) + self.nonShape.Walk(path, visit) + self.nonnegativeIntegerProp.Walk(path, visit) + self.positiveIntegerProp.Walk(path, visit) + self.regex.Walk(path, visit) + self.regexDatetime.Walk(path, visit) + self.regexDatetimestamp.Walk(path, visit) + self.regexList.Walk(path, visit) + self.stringListNoDatatype.Walk(path, visit) + self.stringListProp.Walk(path, visit) + self.stringScalarProp.Walk(path, visit) +} + + +func (self *HttpExampleOrgTestClassObject) Encode() PropertyInterface[string] { return &self.encode } +func (self *HttpExampleOrgTestClassObject) Import() PropertyInterface[string] { return &self.import_ } +func (self *HttpExampleOrgTestClassObject) AnyuriProp() PropertyInterface[string] { return &self.anyuriProp } +func (self *HttpExampleOrgTestClassObject) BooleanProp() PropertyInterface[bool] { return &self.booleanProp } +func (self *HttpExampleOrgTestClassObject) ClassListProp() ListPropertyInterface[Ref[HttpExampleOrgTestClass]] { return &self.classListProp } +func (self *HttpExampleOrgTestClassObject) ClassProp() RefPropertyInterface[HttpExampleOrgTestClass] { return &self.classProp } +func (self *HttpExampleOrgTestClassObject) ClassPropNoClass() RefPropertyInterface[HttpExampleOrgTestClass] { return &self.classPropNoClass } +func (self *HttpExampleOrgTestClassObject) DatetimeListProp() ListPropertyInterface[time.Time] { return &self.datetimeListProp } +func (self *HttpExampleOrgTestClassObject) DatetimeScalarProp() PropertyInterface[time.Time] { return &self.datetimeScalarProp } +func (self *HttpExampleOrgTestClassObject) DatetimestampScalarProp() PropertyInterface[time.Time] { return &self.datetimestampScalarProp } +func (self *HttpExampleOrgTestClassObject) EnumListProp() ListPropertyInterface[string] { return &self.enumListProp } +func (self *HttpExampleOrgTestClassObject) EnumProp() PropertyInterface[string] { return &self.enumProp } +func (self *HttpExampleOrgTestClassObject) EnumPropNoClass() PropertyInterface[string] { return &self.enumPropNoClass } +func (self *HttpExampleOrgTestClassObject) FloatProp() PropertyInterface[float64] { return &self.floatProp } +func (self *HttpExampleOrgTestClassObject) IntegerProp() PropertyInterface[int] { return &self.integerProp } +func (self *HttpExampleOrgTestClassObject) NamedProperty() PropertyInterface[string] { return &self.namedProperty } +func (self *HttpExampleOrgTestClassObject) NonShape() RefPropertyInterface[HttpExampleOrgNonShapeClass] { return &self.nonShape } +func (self *HttpExampleOrgTestClassObject) NonnegativeIntegerProp() PropertyInterface[int] { return &self.nonnegativeIntegerProp } +func (self *HttpExampleOrgTestClassObject) PositiveIntegerProp() PropertyInterface[int] { return &self.positiveIntegerProp } +func (self *HttpExampleOrgTestClassObject) Regex() PropertyInterface[string] { return &self.regex } +func (self *HttpExampleOrgTestClassObject) RegexDatetime() PropertyInterface[time.Time] { return &self.regexDatetime } +func (self *HttpExampleOrgTestClassObject) RegexDatetimestamp() PropertyInterface[time.Time] { return &self.regexDatetimestamp } +func (self *HttpExampleOrgTestClassObject) RegexList() ListPropertyInterface[string] { return &self.regexList } +func (self *HttpExampleOrgTestClassObject) StringListNoDatatype() ListPropertyInterface[string] { return &self.stringListNoDatatype } +func (self *HttpExampleOrgTestClassObject) StringListProp() ListPropertyInterface[string] { return &self.stringListProp } +func (self *HttpExampleOrgTestClassObject) StringScalarProp() PropertyInterface[string] { return &self.stringScalarProp } + +func (self *HttpExampleOrgTestClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.HttpExampleOrgParentClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + if self.encode.IsSet() { + val, err := EncodeString(self.encode.Get(), path.PushPath("encode"), httpExampleOrgTestClassEncodeContext, state) + if err != nil { + return err + } + data["http://example.org/encode"] = val + } + if self.import_.IsSet() { + val, err := EncodeString(self.import_.Get(), path.PushPath("import_"), httpExampleOrgTestClassImportContext, state) + if err != nil { + return err + } + data["http://example.org/import"] = val + } + if self.anyuriProp.IsSet() { + val, err := EncodeString(self.anyuriProp.Get(), path.PushPath("anyuriProp"), httpExampleOrgTestClassAnyuriPropContext, state) + if err != nil { + return err + } + data["http://example.org/test-class/anyuri-prop"] = val + } + if self.booleanProp.IsSet() { + val, err := EncodeBoolean(self.booleanProp.Get(), path.PushPath("booleanProp"), httpExampleOrgTestClassBooleanPropContext, state) + if err != nil { + return err + } + data["http://example.org/test-class/boolean-prop"] = val + } + if self.classListProp.IsSet() { + val, err := EncodeList[Ref[HttpExampleOrgTestClass]](self.classListProp.Get(), path.PushPath("classListProp"), httpExampleOrgTestClassClassListPropContext, state, EncodeRef[HttpExampleOrgTestClass]) + if err != nil { + return err + } + data["http://example.org/test-class/class-list-prop"] = val + } + if self.classProp.IsSet() { + val, err := EncodeRef[HttpExampleOrgTestClass](self.classProp.Get(), path.PushPath("classProp"), httpExampleOrgTestClassClassPropContext, state) + if err != nil { + return err + } + data["http://example.org/test-class/class-prop"] = val + } + if self.classPropNoClass.IsSet() { + val, err := EncodeRef[HttpExampleOrgTestClass](self.classPropNoClass.Get(), path.PushPath("classPropNoClass"), httpExampleOrgTestClassClassPropNoClassContext, state) + if err != nil { + return err + } + data["http://example.org/test-class/class-prop-no-class"] = val + } + if self.datetimeListProp.IsSet() { + val, err := EncodeList[time.Time](self.datetimeListProp.Get(), path.PushPath("datetimeListProp"), httpExampleOrgTestClassDatetimeListPropContext, state, EncodeDateTime) + if err != nil { + return err + } + data["http://example.org/test-class/datetime-list-prop"] = val + } + if self.datetimeScalarProp.IsSet() { + val, err := EncodeDateTime(self.datetimeScalarProp.Get(), path.PushPath("datetimeScalarProp"), httpExampleOrgTestClassDatetimeScalarPropContext, state) + if err != nil { + return err + } + data["http://example.org/test-class/datetime-scalar-prop"] = val + } + if self.datetimestampScalarProp.IsSet() { + val, err := EncodeDateTime(self.datetimestampScalarProp.Get(), path.PushPath("datetimestampScalarProp"), httpExampleOrgTestClassDatetimestampScalarPropContext, state) + if err != nil { + return err + } + data["http://example.org/test-class/datetimestamp-scalar-prop"] = val + } + if self.enumListProp.IsSet() { + val, err := EncodeList[string](self.enumListProp.Get(), path.PushPath("enumListProp"), httpExampleOrgTestClassEnumListPropContext, state, EncodeIRI) + if err != nil { + return err + } + data["http://example.org/test-class/enum-list-prop"] = val + } + if self.enumProp.IsSet() { + val, err := EncodeIRI(self.enumProp.Get(), path.PushPath("enumProp"), httpExampleOrgTestClassEnumPropContext, state) + if err != nil { + return err + } + data["http://example.org/test-class/enum-prop"] = val + } + if self.enumPropNoClass.IsSet() { + val, err := EncodeIRI(self.enumPropNoClass.Get(), path.PushPath("enumPropNoClass"), httpExampleOrgTestClassEnumPropNoClassContext, state) + if err != nil { + return err + } + data["http://example.org/test-class/enum-prop-no-class"] = val + } + if self.floatProp.IsSet() { + val, err := EncodeFloat(self.floatProp.Get(), path.PushPath("floatProp"), httpExampleOrgTestClassFloatPropContext, state) + if err != nil { + return err + } + data["http://example.org/test-class/float-prop"] = val + } + if self.integerProp.IsSet() { + val, err := EncodeInteger(self.integerProp.Get(), path.PushPath("integerProp"), httpExampleOrgTestClassIntegerPropContext, state) + if err != nil { + return err + } + data["http://example.org/test-class/integer-prop"] = val + } + if self.namedProperty.IsSet() { + val, err := EncodeString(self.namedProperty.Get(), path.PushPath("namedProperty"), httpExampleOrgTestClassNamedPropertyContext, state) + if err != nil { + return err + } + data["http://example.org/test-class/named-property"] = val + } + if self.nonShape.IsSet() { + val, err := EncodeRef[HttpExampleOrgNonShapeClass](self.nonShape.Get(), path.PushPath("nonShape"), httpExampleOrgTestClassNonShapeContext, state) + if err != nil { + return err + } + data["http://example.org/test-class/non-shape"] = val + } + if self.nonnegativeIntegerProp.IsSet() { + val, err := EncodeInteger(self.nonnegativeIntegerProp.Get(), path.PushPath("nonnegativeIntegerProp"), httpExampleOrgTestClassNonnegativeIntegerPropContext, state) + if err != nil { + return err + } + data["http://example.org/test-class/nonnegative-integer-prop"] = val + } + if self.positiveIntegerProp.IsSet() { + val, err := EncodeInteger(self.positiveIntegerProp.Get(), path.PushPath("positiveIntegerProp"), httpExampleOrgTestClassPositiveIntegerPropContext, state) + if err != nil { + return err + } + data["http://example.org/test-class/positive-integer-prop"] = val + } + if self.regex.IsSet() { + val, err := EncodeString(self.regex.Get(), path.PushPath("regex"), httpExampleOrgTestClassRegexContext, state) + if err != nil { + return err + } + data["http://example.org/test-class/regex"] = val + } + if self.regexDatetime.IsSet() { + val, err := EncodeDateTime(self.regexDatetime.Get(), path.PushPath("regexDatetime"), httpExampleOrgTestClassRegexDatetimeContext, state) + if err != nil { + return err + } + data["http://example.org/test-class/regex-datetime"] = val + } + if self.regexDatetimestamp.IsSet() { + val, err := EncodeDateTime(self.regexDatetimestamp.Get(), path.PushPath("regexDatetimestamp"), httpExampleOrgTestClassRegexDatetimestampContext, state) + if err != nil { + return err + } + data["http://example.org/test-class/regex-datetimestamp"] = val + } + if self.regexList.IsSet() { + val, err := EncodeList[string](self.regexList.Get(), path.PushPath("regexList"), httpExampleOrgTestClassRegexListContext, state, EncodeString) + if err != nil { + return err + } + data["http://example.org/test-class/regex-list"] = val + } + if self.stringListNoDatatype.IsSet() { + val, err := EncodeList[string](self.stringListNoDatatype.Get(), path.PushPath("stringListNoDatatype"), httpExampleOrgTestClassStringListNoDatatypeContext, state, EncodeString) + if err != nil { + return err + } + data["http://example.org/test-class/string-list-no-datatype"] = val + } + if self.stringListProp.IsSet() { + val, err := EncodeList[string](self.stringListProp.Get(), path.PushPath("stringListProp"), httpExampleOrgTestClassStringListPropContext, state, EncodeString) + if err != nil { + return err + } + data["http://example.org/test-class/string-list-prop"] = val + } + if self.stringScalarProp.IsSet() { + val, err := EncodeString(self.stringScalarProp.Get(), path.PushPath("stringScalarProp"), httpExampleOrgTestClassStringScalarPropContext, state) + if err != nil { + return err + } + data["http://example.org/test-class/string-scalar-prop"] = val + } + return nil +} +type HttpExampleOrgTestClassRequiredObject struct { + HttpExampleOrgTestClassObject + + // A required string list property + requiredStringListProp ListProperty[string] + // A required scalar string property + requiredStringScalarProp Property[string] +} + + +type HttpExampleOrgTestClassRequiredObjectType struct { + SHACLTypeBase +} +var httpExampleOrgTestClassRequiredType HttpExampleOrgTestClassRequiredObjectType +var httpExampleOrgTestClassRequiredRequiredStringListPropContext = map[string]string{} +var httpExampleOrgTestClassRequiredRequiredStringScalarPropContext = map[string]string{} + +func DecodeHttpExampleOrgTestClassRequired (data any, path Path, context map[string]string) (Ref[HttpExampleOrgTestClassRequired], error) { + return DecodeRef[HttpExampleOrgTestClassRequired](data, path, context, httpExampleOrgTestClassRequiredType) +} + +func (self HttpExampleOrgTestClassRequiredObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgTestClassRequired) + _ = obj + switch name { + case "http://example.org/test-class/required-string-list-prop": + val, err := DecodeList[string](value, path, httpExampleOrgTestClassRequiredRequiredStringListPropContext, DecodeString) + if err != nil { + return false, err + } + err = obj.RequiredStringListProp().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/test-class/required-string-scalar-prop": + val, err := DecodeString(value, path, httpExampleOrgTestClassRequiredRequiredStringScalarPropContext) + if err != nil { + return false, err + } + err = obj.RequiredStringScalarProp().Set(val) + if err != nil { + return false, err + } + return true, nil + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgTestClassRequiredObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgTestClassRequiredObject(&HttpExampleOrgTestClassRequiredObject{}, self) +} + +func ConstructHttpExampleOrgTestClassRequiredObject(o *HttpExampleOrgTestClassRequiredObject, typ SHACLType) *HttpExampleOrgTestClassRequiredObject { + ConstructHttpExampleOrgTestClassObject(&o.HttpExampleOrgTestClassObject, typ) + { + validators := []Validator[string]{} + o.requiredStringListProp = NewListProperty[string]("requiredStringListProp", validators) + } + { + validators := []Validator[string]{} + o.requiredStringScalarProp = NewProperty[string]("requiredStringScalarProp", validators) + } + return o +} + +type HttpExampleOrgTestClassRequired interface { + HttpExampleOrgTestClass + RequiredStringListProp() ListPropertyInterface[string] + RequiredStringScalarProp() PropertyInterface[string] +} + + +func MakeHttpExampleOrgTestClassRequired() HttpExampleOrgTestClassRequired { + return ConstructHttpExampleOrgTestClassRequiredObject(&HttpExampleOrgTestClassRequiredObject{}, httpExampleOrgTestClassRequiredType) +} + +func MakeHttpExampleOrgTestClassRequiredRef() Ref[HttpExampleOrgTestClassRequired] { + o := MakeHttpExampleOrgTestClassRequired() + return MakeObjectRef[HttpExampleOrgTestClassRequired](o) +} + +func (self *HttpExampleOrgTestClassRequiredObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.HttpExampleOrgTestClassObject.Validate(path, handler) { + valid = false + } + { + prop_path := path.PushPath("requiredStringListProp") + if ! self.requiredStringListProp.Check(prop_path, handler) { + valid = false + } + if len(self.requiredStringListProp.Get()) < 1 { + if handler != nil { + handler.HandleError(&ValidationError{ + "requiredStringListProp", + "Too few elements. Minimum of 1 required"}, + prop_path) + } + valid = false + } + if len(self.requiredStringListProp.Get()) > 2 { + if handler != nil { + handler.HandleError(&ValidationError{ + "requiredStringListProp", + "Too many elements. Maximum of 2 allowed"}, + prop_path) + } + valid = false + } + } + { + prop_path := path.PushPath("requiredStringScalarProp") + if ! self.requiredStringScalarProp.Check(prop_path, handler) { + valid = false + } + if ! self.requiredStringScalarProp.IsSet() { + if handler != nil { + handler.HandleError(&ValidationError{"requiredStringScalarProp", "Value is required"}, prop_path) + } + valid = false + } + } + return valid +} + +func (self *HttpExampleOrgTestClassRequiredObject) Walk(path Path, visit Visit) { + self.HttpExampleOrgTestClassObject.Walk(path, visit) + self.requiredStringListProp.Walk(path, visit) + self.requiredStringScalarProp.Walk(path, visit) +} + + +func (self *HttpExampleOrgTestClassRequiredObject) RequiredStringListProp() ListPropertyInterface[string] { return &self.requiredStringListProp } +func (self *HttpExampleOrgTestClassRequiredObject) RequiredStringScalarProp() PropertyInterface[string] { return &self.requiredStringScalarProp } + +func (self *HttpExampleOrgTestClassRequiredObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.HttpExampleOrgTestClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + if self.requiredStringListProp.IsSet() { + val, err := EncodeList[string](self.requiredStringListProp.Get(), path.PushPath("requiredStringListProp"), httpExampleOrgTestClassRequiredRequiredStringListPropContext, state, EncodeString) + if err != nil { + return err + } + data["http://example.org/test-class/required-string-list-prop"] = val + } + if self.requiredStringScalarProp.IsSet() { + val, err := EncodeString(self.requiredStringScalarProp.Get(), path.PushPath("requiredStringScalarProp"), httpExampleOrgTestClassRequiredRequiredStringScalarPropContext, state) + if err != nil { + return err + } + data["http://example.org/test-class/required-string-scalar-prop"] = val + } + return nil +} + +// A class derived from test-class +type HttpExampleOrgTestDerivedClassObject struct { + HttpExampleOrgTestClassObject + + // A string property in a derived class + stringProp Property[string] +} + + +type HttpExampleOrgTestDerivedClassObjectType struct { + SHACLTypeBase +} +var httpExampleOrgTestDerivedClassType HttpExampleOrgTestDerivedClassObjectType +var httpExampleOrgTestDerivedClassStringPropContext = map[string]string{} + +func DecodeHttpExampleOrgTestDerivedClass (data any, path Path, context map[string]string) (Ref[HttpExampleOrgTestDerivedClass], error) { + return DecodeRef[HttpExampleOrgTestDerivedClass](data, path, context, httpExampleOrgTestDerivedClassType) +} + +func (self HttpExampleOrgTestDerivedClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgTestDerivedClass) + _ = obj + switch name { + case "http://example.org/test-derived-class/string-prop": + val, err := DecodeString(value, path, httpExampleOrgTestDerivedClassStringPropContext) + if err != nil { + return false, err + } + err = obj.StringProp().Set(val) + if err != nil { + return false, err + } + return true, nil + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgTestDerivedClassObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgTestDerivedClassObject(&HttpExampleOrgTestDerivedClassObject{}, self) +} + +func ConstructHttpExampleOrgTestDerivedClassObject(o *HttpExampleOrgTestDerivedClassObject, typ SHACLType) *HttpExampleOrgTestDerivedClassObject { + ConstructHttpExampleOrgTestClassObject(&o.HttpExampleOrgTestClassObject, typ) + { + validators := []Validator[string]{} + o.stringProp = NewProperty[string]("stringProp", validators) + } + return o +} + +type HttpExampleOrgTestDerivedClass interface { + HttpExampleOrgTestClass + StringProp() PropertyInterface[string] +} + + +func MakeHttpExampleOrgTestDerivedClass() HttpExampleOrgTestDerivedClass { + return ConstructHttpExampleOrgTestDerivedClassObject(&HttpExampleOrgTestDerivedClassObject{}, httpExampleOrgTestDerivedClassType) +} + +func MakeHttpExampleOrgTestDerivedClassRef() Ref[HttpExampleOrgTestDerivedClass] { + o := MakeHttpExampleOrgTestDerivedClass() + return MakeObjectRef[HttpExampleOrgTestDerivedClass](o) +} + +func (self *HttpExampleOrgTestDerivedClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.HttpExampleOrgTestClassObject.Validate(path, handler) { + valid = false + } + { + prop_path := path.PushPath("stringProp") + if ! self.stringProp.Check(prop_path, handler) { + valid = false + } + } + return valid +} + +func (self *HttpExampleOrgTestDerivedClassObject) Walk(path Path, visit Visit) { + self.HttpExampleOrgTestClassObject.Walk(path, visit) + self.stringProp.Walk(path, visit) +} + + +func (self *HttpExampleOrgTestDerivedClassObject) StringProp() PropertyInterface[string] { return &self.stringProp } + +func (self *HttpExampleOrgTestDerivedClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.HttpExampleOrgTestClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + if self.stringProp.IsSet() { + val, err := EncodeString(self.stringProp.Get(), path.PushPath("stringProp"), httpExampleOrgTestDerivedClassStringPropContext, state) + if err != nil { + return err + } + data["http://example.org/test-derived-class/string-prop"] = val + } + return nil +} + +// A class that uses an abstract extensible class +type HttpExampleOrgUsesExtensibleAbstractClassObject struct { + SHACLObjectBase + + // A property that references and abstract extensible class + prop RefProperty[HttpExampleOrgExtensibleAbstractClass] +} + + +type HttpExampleOrgUsesExtensibleAbstractClassObjectType struct { + SHACLTypeBase +} +var httpExampleOrgUsesExtensibleAbstractClassType HttpExampleOrgUsesExtensibleAbstractClassObjectType +var httpExampleOrgUsesExtensibleAbstractClassPropContext = map[string]string{} + +func DecodeHttpExampleOrgUsesExtensibleAbstractClass (data any, path Path, context map[string]string) (Ref[HttpExampleOrgUsesExtensibleAbstractClass], error) { + return DecodeRef[HttpExampleOrgUsesExtensibleAbstractClass](data, path, context, httpExampleOrgUsesExtensibleAbstractClassType) +} + +func (self HttpExampleOrgUsesExtensibleAbstractClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgUsesExtensibleAbstractClass) + _ = obj + switch name { + case "http://example.org/uses-extensible-abstract-class/prop": + val, err := DecodeHttpExampleOrgExtensibleAbstractClass(value, path, httpExampleOrgUsesExtensibleAbstractClassPropContext) + if err != nil { + return false, err + } + err = obj.Prop().Set(val) + if err != nil { + return false, err + } + return true, nil + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgUsesExtensibleAbstractClassObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgUsesExtensibleAbstractClassObject(&HttpExampleOrgUsesExtensibleAbstractClassObject{}, self) +} + +func ConstructHttpExampleOrgUsesExtensibleAbstractClassObject(o *HttpExampleOrgUsesExtensibleAbstractClassObject, typ SHACLType) *HttpExampleOrgUsesExtensibleAbstractClassObject { + ConstructSHACLObjectBase(&o.SHACLObjectBase, typ) + { + validators := []Validator[Ref[HttpExampleOrgExtensibleAbstractClass]]{} + o.prop = NewRefProperty[HttpExampleOrgExtensibleAbstractClass]("prop", validators) + } + return o +} + +type HttpExampleOrgUsesExtensibleAbstractClass interface { + SHACLObject + Prop() RefPropertyInterface[HttpExampleOrgExtensibleAbstractClass] +} + + +func MakeHttpExampleOrgUsesExtensibleAbstractClass() HttpExampleOrgUsesExtensibleAbstractClass { + return ConstructHttpExampleOrgUsesExtensibleAbstractClassObject(&HttpExampleOrgUsesExtensibleAbstractClassObject{}, httpExampleOrgUsesExtensibleAbstractClassType) +} + +func MakeHttpExampleOrgUsesExtensibleAbstractClassRef() Ref[HttpExampleOrgUsesExtensibleAbstractClass] { + o := MakeHttpExampleOrgUsesExtensibleAbstractClass() + return MakeObjectRef[HttpExampleOrgUsesExtensibleAbstractClass](o) +} + +func (self *HttpExampleOrgUsesExtensibleAbstractClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.SHACLObjectBase.Validate(path, handler) { + valid = false + } + { + prop_path := path.PushPath("prop") + if ! self.prop.Check(prop_path, handler) { + valid = false + } + if ! self.prop.IsSet() { + if handler != nil { + handler.HandleError(&ValidationError{"prop", "Value is required"}, prop_path) + } + valid = false + } + } + return valid +} + +func (self *HttpExampleOrgUsesExtensibleAbstractClassObject) Walk(path Path, visit Visit) { + self.SHACLObjectBase.Walk(path, visit) + self.prop.Walk(path, visit) +} + + +func (self *HttpExampleOrgUsesExtensibleAbstractClassObject) Prop() RefPropertyInterface[HttpExampleOrgExtensibleAbstractClass] { return &self.prop } + +func (self *HttpExampleOrgUsesExtensibleAbstractClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.SHACLObjectBase.EncodeProperties(data, path, state); err != nil { + return err + } + if self.prop.IsSet() { + val, err := EncodeRef[HttpExampleOrgExtensibleAbstractClass](self.prop.Get(), path.PushPath("prop"), httpExampleOrgUsesExtensibleAbstractClassPropContext, state) + if err != nil { + return err + } + data["http://example.org/uses-extensible-abstract-class/prop"] = val + } + return nil +} + +// Derived class that sorts before the parent to test ordering +type HttpExampleOrgAaaDerivedClassObject struct { + HttpExampleOrgParentClassObject + +} + + +type HttpExampleOrgAaaDerivedClassObjectType struct { + SHACLTypeBase +} +var httpExampleOrgAaaDerivedClassType HttpExampleOrgAaaDerivedClassObjectType + +func DecodeHttpExampleOrgAaaDerivedClass (data any, path Path, context map[string]string) (Ref[HttpExampleOrgAaaDerivedClass], error) { + return DecodeRef[HttpExampleOrgAaaDerivedClass](data, path, context, httpExampleOrgAaaDerivedClassType) +} + +func (self HttpExampleOrgAaaDerivedClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgAaaDerivedClass) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgAaaDerivedClassObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgAaaDerivedClassObject(&HttpExampleOrgAaaDerivedClassObject{}, self) +} + +func ConstructHttpExampleOrgAaaDerivedClassObject(o *HttpExampleOrgAaaDerivedClassObject, typ SHACLType) *HttpExampleOrgAaaDerivedClassObject { + ConstructHttpExampleOrgParentClassObject(&o.HttpExampleOrgParentClassObject, typ) + return o +} + +type HttpExampleOrgAaaDerivedClass interface { + HttpExampleOrgParentClass +} + + +func MakeHttpExampleOrgAaaDerivedClass() HttpExampleOrgAaaDerivedClass { + return ConstructHttpExampleOrgAaaDerivedClassObject(&HttpExampleOrgAaaDerivedClassObject{}, httpExampleOrgAaaDerivedClassType) +} + +func MakeHttpExampleOrgAaaDerivedClassRef() Ref[HttpExampleOrgAaaDerivedClass] { + o := MakeHttpExampleOrgAaaDerivedClass() + return MakeObjectRef[HttpExampleOrgAaaDerivedClass](o) +} + +func (self *HttpExampleOrgAaaDerivedClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.HttpExampleOrgParentClassObject.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *HttpExampleOrgAaaDerivedClassObject) Walk(path Path, visit Visit) { + self.HttpExampleOrgParentClassObject.Walk(path, visit) +} + + + +func (self *HttpExampleOrgAaaDerivedClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.HttpExampleOrgParentClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// A class that derives its nodeKind from parent +type HttpExampleOrgDerivedNodeKindIriObject struct { + HttpExampleOrgNodeKindIriObject + +} + + +type HttpExampleOrgDerivedNodeKindIriObjectType struct { + SHACLTypeBase +} +var httpExampleOrgDerivedNodeKindIriType HttpExampleOrgDerivedNodeKindIriObjectType + +func DecodeHttpExampleOrgDerivedNodeKindIri (data any, path Path, context map[string]string) (Ref[HttpExampleOrgDerivedNodeKindIri], error) { + return DecodeRef[HttpExampleOrgDerivedNodeKindIri](data, path, context, httpExampleOrgDerivedNodeKindIriType) +} + +func (self HttpExampleOrgDerivedNodeKindIriObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgDerivedNodeKindIri) + _ = obj + switch name { + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgDerivedNodeKindIriObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgDerivedNodeKindIriObject(&HttpExampleOrgDerivedNodeKindIriObject{}, self) +} + +func ConstructHttpExampleOrgDerivedNodeKindIriObject(o *HttpExampleOrgDerivedNodeKindIriObject, typ SHACLType) *HttpExampleOrgDerivedNodeKindIriObject { + ConstructHttpExampleOrgNodeKindIriObject(&o.HttpExampleOrgNodeKindIriObject, typ) + return o +} + +type HttpExampleOrgDerivedNodeKindIri interface { + HttpExampleOrgNodeKindIri +} + + +func MakeHttpExampleOrgDerivedNodeKindIri() HttpExampleOrgDerivedNodeKindIri { + return ConstructHttpExampleOrgDerivedNodeKindIriObject(&HttpExampleOrgDerivedNodeKindIriObject{}, httpExampleOrgDerivedNodeKindIriType) +} + +func MakeHttpExampleOrgDerivedNodeKindIriRef() Ref[HttpExampleOrgDerivedNodeKindIri] { + o := MakeHttpExampleOrgDerivedNodeKindIri() + return MakeObjectRef[HttpExampleOrgDerivedNodeKindIri](o) +} + +func (self *HttpExampleOrgDerivedNodeKindIriObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.HttpExampleOrgNodeKindIriObject.Validate(path, handler) { + valid = false + } + return valid +} + +func (self *HttpExampleOrgDerivedNodeKindIriObject) Walk(path Path, visit Visit) { + self.HttpExampleOrgNodeKindIriObject.Walk(path, visit) +} + + + +func (self *HttpExampleOrgDerivedNodeKindIriObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.HttpExampleOrgNodeKindIriObject.EncodeProperties(data, path, state); err != nil { + return err + } + return nil +} + +// An extensible class +type HttpExampleOrgExtensibleClassObject struct { + HttpExampleOrgLinkClassObject + SHACLExtensibleBase + + // An extensible property + property Property[string] + // A required extensible property + required Property[string] +} + + +type HttpExampleOrgExtensibleClassObjectType struct { + SHACLTypeBase +} +var httpExampleOrgExtensibleClassType HttpExampleOrgExtensibleClassObjectType +var httpExampleOrgExtensibleClassPropertyContext = map[string]string{} +var httpExampleOrgExtensibleClassRequiredContext = map[string]string{} + +func DecodeHttpExampleOrgExtensibleClass (data any, path Path, context map[string]string) (Ref[HttpExampleOrgExtensibleClass], error) { + return DecodeRef[HttpExampleOrgExtensibleClass](data, path, context, httpExampleOrgExtensibleClassType) +} + +func (self HttpExampleOrgExtensibleClassObjectType) DecodeProperty(o SHACLObject, name string, value interface{}, path Path) (bool, error) { + obj := o.(HttpExampleOrgExtensibleClass) + _ = obj + switch name { + case "http://example.org/extensible-class/property": + val, err := DecodeString(value, path, httpExampleOrgExtensibleClassPropertyContext) + if err != nil { + return false, err + } + err = obj.Property().Set(val) + if err != nil { + return false, err + } + return true, nil + case "http://example.org/extensible-class/required": + val, err := DecodeString(value, path, httpExampleOrgExtensibleClassRequiredContext) + if err != nil { + return false, err + } + err = obj.Required().Set(val) + if err != nil { + return false, err + } + return true, nil + default: + found, err := self.SHACLTypeBase.DecodeProperty(o, name, value, path) + if err != nil || found { + return found, err + } + } + + return false, nil +} + +func (self HttpExampleOrgExtensibleClassObjectType) Create() SHACLObject { + return ConstructHttpExampleOrgExtensibleClassObject(&HttpExampleOrgExtensibleClassObject{}, self) +} + +func ConstructHttpExampleOrgExtensibleClassObject(o *HttpExampleOrgExtensibleClassObject, typ SHACLType) *HttpExampleOrgExtensibleClassObject { + ConstructHttpExampleOrgLinkClassObject(&o.HttpExampleOrgLinkClassObject, typ) + { + validators := []Validator[string]{} + o.property = NewProperty[string]("property", validators) + } + { + validators := []Validator[string]{} + o.required = NewProperty[string]("required", validators) + } + return o +} + +type HttpExampleOrgExtensibleClass interface { + HttpExampleOrgLinkClass + Property() PropertyInterface[string] + Required() PropertyInterface[string] +} + + +func MakeHttpExampleOrgExtensibleClass() HttpExampleOrgExtensibleClass { + return ConstructHttpExampleOrgExtensibleClassObject(&HttpExampleOrgExtensibleClassObject{}, httpExampleOrgExtensibleClassType) +} + +func MakeHttpExampleOrgExtensibleClassRef() Ref[HttpExampleOrgExtensibleClass] { + o := MakeHttpExampleOrgExtensibleClass() + return MakeObjectRef[HttpExampleOrgExtensibleClass](o) +} + +func (self *HttpExampleOrgExtensibleClassObject) Validate(path Path, handler ErrorHandler) bool { + var valid bool = true + if ! self.HttpExampleOrgLinkClassObject.Validate(path, handler) { + valid = false + } + { + prop_path := path.PushPath("property") + if ! self.property.Check(prop_path, handler) { + valid = false + } + } + { + prop_path := path.PushPath("required") + if ! self.required.Check(prop_path, handler) { + valid = false + } + if ! self.required.IsSet() { + if handler != nil { + handler.HandleError(&ValidationError{"required", "Value is required"}, prop_path) + } + valid = false + } + } + return valid +} + +func (self *HttpExampleOrgExtensibleClassObject) Walk(path Path, visit Visit) { + self.HttpExampleOrgLinkClassObject.Walk(path, visit) + self.property.Walk(path, visit) + self.required.Walk(path, visit) +} + + +func (self *HttpExampleOrgExtensibleClassObject) Property() PropertyInterface[string] { return &self.property } +func (self *HttpExampleOrgExtensibleClassObject) Required() PropertyInterface[string] { return &self.required } + +func (self *HttpExampleOrgExtensibleClassObject) EncodeProperties(data map[string]interface{}, path Path, state *EncodeState) error { + if err := self.HttpExampleOrgLinkClassObject.EncodeProperties(data, path, state); err != nil { + return err + } + if self.property.IsSet() { + val, err := EncodeString(self.property.Get(), path.PushPath("property"), httpExampleOrgExtensibleClassPropertyContext, state) + if err != nil { + return err + } + data["http://example.org/extensible-class/property"] = val + } + if self.required.IsSet() { + val, err := EncodeString(self.required.Get(), path.PushPath("required"), httpExampleOrgExtensibleClassRequiredContext, state) + if err != nil { + return err + } + data["http://example.org/extensible-class/required"] = val + } + self.SHACLExtensibleBase.EncodeExtProperties(data, path) + return nil +} + + +func init() { + objectTypes = make(map[string] SHACLType) + httpExampleOrgAbstractClassType = HttpExampleOrgAbstractClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/abstract-class", + isAbstract: true, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + }, + }, + } + RegisterType(httpExampleOrgAbstractClassType) + httpExampleOrgAbstractShClassType = HttpExampleOrgAbstractShClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/abstract-sh-class", + isAbstract: true, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + }, + }, + } + RegisterType(httpExampleOrgAbstractShClassType) + httpExampleOrgAbstractSpdxClassType = HttpExampleOrgAbstractSpdxClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/abstract-spdx-class", + isAbstract: true, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + }, + }, + } + RegisterType(httpExampleOrgAbstractSpdxClassType) + httpExampleOrgConcreteClassType = HttpExampleOrgConcreteClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/concrete-class", + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + "http://example.org/abstract-class", + }, + }, + } + RegisterType(httpExampleOrgConcreteClassType) + httpExampleOrgConcreteShClassType = HttpExampleOrgConcreteShClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/concrete-sh-class", + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + "http://example.org/abstract-sh-class", + }, + }, + } + RegisterType(httpExampleOrgConcreteShClassType) + httpExampleOrgConcreteSpdxClassType = HttpExampleOrgConcreteSpdxClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/concrete-spdx-class", + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + "http://example.org/abstract-spdx-class", + }, + }, + } + RegisterType(httpExampleOrgConcreteSpdxClassType) + httpExampleOrgEnumTypeType = HttpExampleOrgEnumTypeObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/enumType", + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + }, + }, + } + RegisterType(httpExampleOrgEnumTypeType) + httpExampleOrgExtensibleAbstractClassType = HttpExampleOrgExtensibleAbstractClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/extensible-abstract-class", + isAbstract: true, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + isExtensible: NewOptional[bool](true), + parentIRIs: []string{ + }, + }, + } + RegisterType(httpExampleOrgExtensibleAbstractClassType) + httpExampleOrgIdPropClassType = HttpExampleOrgIdPropClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/id-prop-class", + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + idAlias: NewOptional[string]("testid"), + parentIRIs: []string{ + }, + }, + } + RegisterType(httpExampleOrgIdPropClassType) + httpExampleOrgInheritedIdPropClassType = HttpExampleOrgInheritedIdPropClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/inherited-id-prop-class", + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + idAlias: NewOptional[string]("testid"), + parentIRIs: []string{ + "http://example.org/id-prop-class", + }, + }, + } + RegisterType(httpExampleOrgInheritedIdPropClassType) + httpExampleOrgLinkClassType = HttpExampleOrgLinkClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/link-class", + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + }, + }, + } + RegisterType(httpExampleOrgLinkClassType) + httpExampleOrgLinkDerivedClassType = HttpExampleOrgLinkDerivedClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/link-derived-class", + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + "http://example.org/link-class", + }, + }, + } + RegisterType(httpExampleOrgLinkDerivedClassType) + httpExampleOrgNodeKindBlankType = HttpExampleOrgNodeKindBlankObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/node-kind-blank", + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNode), + parentIRIs: []string{ + "http://example.org/link-class", + }, + }, + } + RegisterType(httpExampleOrgNodeKindBlankType) + httpExampleOrgNodeKindIriType = HttpExampleOrgNodeKindIriObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/node-kind-iri", + isAbstract: false, + nodeKind: NewOptional[int](NodeKindIRI), + parentIRIs: []string{ + "http://example.org/link-class", + }, + }, + } + RegisterType(httpExampleOrgNodeKindIriType) + httpExampleOrgNodeKindIriOrBlankType = HttpExampleOrgNodeKindIriOrBlankObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/node-kind-iri-or-blank", + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + "http://example.org/link-class", + }, + }, + } + RegisterType(httpExampleOrgNodeKindIriOrBlankType) + httpExampleOrgNonShapeClassType = HttpExampleOrgNonShapeClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/non-shape-class", + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + }, + }, + } + RegisterType(httpExampleOrgNonShapeClassType) + httpExampleOrgParentClassType = HttpExampleOrgParentClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/parent-class", + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + }, + }, + } + RegisterType(httpExampleOrgParentClassType) + httpExampleOrgRequiredAbstractType = HttpExampleOrgRequiredAbstractObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/required-abstract", + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + }, + }, + } + RegisterType(httpExampleOrgRequiredAbstractType) + httpExampleOrgTestAnotherClassType = HttpExampleOrgTestAnotherClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/test-another-class", + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + }, + }, + } + RegisterType(httpExampleOrgTestAnotherClassType) + httpExampleOrgTestClassType = HttpExampleOrgTestClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/test-class", + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + "http://example.org/parent-class", + }, + }, + } + RegisterType(httpExampleOrgTestClassType) + httpExampleOrgTestClassRequiredType = HttpExampleOrgTestClassRequiredObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/test-class-required", + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + "http://example.org/test-class", + }, + }, + } + RegisterType(httpExampleOrgTestClassRequiredType) + httpExampleOrgTestDerivedClassType = HttpExampleOrgTestDerivedClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/test-derived-class", + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + "http://example.org/test-class", + }, + }, + } + RegisterType(httpExampleOrgTestDerivedClassType) + httpExampleOrgUsesExtensibleAbstractClassType = HttpExampleOrgUsesExtensibleAbstractClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/uses-extensible-abstract-class", + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + }, + }, + } + RegisterType(httpExampleOrgUsesExtensibleAbstractClassType) + httpExampleOrgAaaDerivedClassType = HttpExampleOrgAaaDerivedClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/aaa-derived-class", + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + parentIRIs: []string{ + "http://example.org/parent-class", + }, + }, + } + RegisterType(httpExampleOrgAaaDerivedClassType) + httpExampleOrgDerivedNodeKindIriType = HttpExampleOrgDerivedNodeKindIriObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/derived-node-kind-iri", + isAbstract: false, + nodeKind: NewOptional[int](NodeKindIRI), + parentIRIs: []string{ + "http://example.org/node-kind-iri", + }, + }, + } + RegisterType(httpExampleOrgDerivedNodeKindIriType) + httpExampleOrgExtensibleClassType = HttpExampleOrgExtensibleClassObjectType{ + SHACLTypeBase: SHACLTypeBase{ + typeIRI: "http://example.org/extensible-class", + isAbstract: false, + nodeKind: NewOptional[int](NodeKindBlankNodeOrIRI), + isExtensible: NewOptional[bool](true), + parentIRIs: []string{ + "http://example.org/link-class", + }, + }, + } + RegisterType(httpExampleOrgExtensibleClassType) +} diff --git a/tests/expect/make_expect.py b/tests/expect/make_expect.py index 194fc1f..af5460d 100755 --- a/tests/expect/make_expect.py +++ b/tests/expect/make_expect.py @@ -29,7 +29,7 @@ def main(): context = src.parent / (src.stem + "-context.json") - for lang, ext in (("python", ".py"), ("jsonschema", ".json"), ("cpp", "")): + for lang, ext in (("python", ".py"), ("jsonschema", ".json"), ("cpp", ""), ("golang", ".go")): subprocess.run( [ "shacl2code", diff --git a/tests/test_golang.py b/tests/test_golang.py new file mode 100644 index 0000000..c5d4f3d --- /dev/null +++ b/tests/test_golang.py @@ -0,0 +1,873 @@ +# +# Copyright (c) 2024 Joshua Watt +# +# SPDX-License-Identifier: MIT + +import json +import pytest +import re +import subprocess +import textwrap +import multiprocessing +from pathlib import Path +from enum import Enum +from dataclasses import dataclass +import jsonvalidation + +THIS_FILE = Path(__file__) +THIS_DIR = THIS_FILE.parent + +EXPECT_DIR = THIS_DIR / "expect" +DATA_DIR = THIS_DIR / "data" + +TEST_MODEL = THIS_DIR / "data" / "model" / "test.ttl" + +TEST_CONTEXT = THIS_DIR / "data" / "model" / "test-context.json" + +SPDX3_CONTEXT_URL = "https://spdx.github.io/spdx-3-model/context.json" + + +@pytest.fixture(scope="module") +def test_lib(tmp_path_factory, model_server): + libdir = tmp_path_factory.mktemp("lib") + model_source = libdir / "model.go" + + subprocess.run( + [ + "shacl2code", + "generate", + "--input", + TEST_MODEL, + "--context", + model_server + "/test-context.json", + "golang", + "--output", + model_source, + ], + check=True, + ) + + subprocess.run(["go", "mod", "init", "model"], cwd=libdir, check=True) + subprocess.run(["go", "mod", "tidy"], cwd=libdir, check=True) + + model_output = libdir / "model.a" + + subprocess.run( + ["go", "build", "-o", model_output, "."], + cwd=libdir, + check=True, + ) + + return libdir + + +class Progress(Enum): + COMPILE_FAILS = 0 + RUN_FAILS = 1 + VALIDATION_FAILS = 2 + RUNS = 3 + + +@pytest.fixture +def compile_test(test_lib, tmp_path): + def f(code_fragment, *, progress=Progress.RUNS, static=False, imports=[]): + subprocess.run( + ["go", "mod", "init", "test"], + cwd=tmp_path, + check=True, + ) + + subprocess.run( + ["go", "mod", "edit", "-replace", f"model={test_lib}"], + cwd=tmp_path, + check=True, + ) + + src = tmp_path / "test.go" + import_str = "\n".join(f' "{i}"' for i in imports) + src.write_text( + textwrap.dedent( + f"""\ + package main + + import ( + "os" + "model" + "fmt" + {import_str} + ) + + func test() error {{ + """ + ) + + textwrap.dedent(code_fragment) + + textwrap.dedent( + """\ + return nil + } + + func convertRefUnchecked[TO model.SHACLObject, FROM model.SHACLObject](in model.Ref[FROM]) model.Ref[TO] { + r, err := model.ConvertRef[TO, FROM](in) + if err != nil { + panic(err) + } + return r + } + + + func main() { + // This is necessary so that the model import doesn't + // generate an error + model.IsIRI("") + err := test() + if err == nil { + os.Exit(0) + } + switch err.(type) { + case *model.ValidationError: + fmt.Println("VALIDATION_FAILS", err) + default: + fmt.Println("ERROR", err) + } + os.Exit(1) + } + """ + ) + ) + subprocess.run(["go", "mod", "tidy"], cwd=tmp_path, check=True) + + prog = tmp_path / "prog" + + p = subprocess.run( + ["go", "build", "-o", prog, "."], + cwd=tmp_path, + ) + + if progress == Progress.COMPILE_FAILS: + assert ( + p.returncode != 0 + ), f"Compile succeeded when failure was expected. Output: {p.stdout}" + return None + + assert p.returncode == 0, f"Compile failed. Output: {p.stdout}" + + prog.chmod(0o755) + + p = subprocess.run( + [prog], + stdout=subprocess.PIPE, + encoding="utf-8", + ) + + if progress == Progress.RUN_FAILS: + assert ( + p.returncode != 0 + ), f"Run succeeded when failure was expected. Output: {p.stdout}" + return None + + for e in Progress: + if e == Progress.RUNS: + continue + + if progress == e: + assert ( + p.returncode != 0 + ), f"Run succeeded when failure was expected. Output: {p.stdout}" + + assert ( + e.name in p.stdout.rstrip() + ), f"{e.name} was not raised in program. Output: {p.stdout}" + return None + + assert p.returncode == 0, f"Run failed. Output: {p.stdout}" + + return p.stdout + + yield f + + +@pytest.fixture(scope="module") +def validate_test(test_lib, tmp_path_factory): + tmp_path = tmp_path_factory.mktemp("validate") + subprocess.run( + ["go", "mod", "init", "validate"], + cwd=tmp_path, + check=True, + ) + + subprocess.run( + ["go", "mod", "edit", "-replace", f"model={test_lib}"], + cwd=tmp_path, + check=True, + ) + + src = tmp_path / "validate.go" + src.write_text( + textwrap.dedent( + """\ + package main + + import ( + "os" + "model" + "fmt" + "encoding/json" + ) + + func main() { + objset := model.NewSHACLObjectSet() + + file, err := os.Open(os.Args[1]) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + defer file.Close() + + decoder := json.NewDecoder(file) + + if err := objset.Decode(decoder); err != nil { + fmt.Println(err) + os.Exit(1) + } + + if ! objset.Validate(nil) { + fmt.Println("Validation failed") + os.Exit(1) + } + os.Exit(0) + } + """ + ) + ) + subprocess.run(["go", "mod", "tidy"], cwd=tmp_path, check=True) + + prog = tmp_path / "validate" + + subprocess.run( + ["go", "build", "-o", prog, "."], + cwd=tmp_path, + check=True, + ) + + def f(path, passes): + p = subprocess.run( + [prog, path], + encoding="utf-8", + ) + if passes: + assert p.returncode == 0, f"Validation failed when a pass was expected" + else: + assert p.returncode != 0, f"Validation passed when a failure was expected" + + yield f + + +@pytest.fixture(scope="module") +def roundtrip_test(test_lib, tmp_path_factory): + tmp_path = tmp_path_factory.mktemp("roundtrip") + subprocess.run( + ["go", "mod", "init", "roundtrip"], + cwd=tmp_path, + check=True, + ) + + subprocess.run( + ["go", "mod", "edit", "-replace", f"model={test_lib}"], + cwd=tmp_path, + check=True, + ) + + src = tmp_path / "roundtrip.go" + src.write_text( + textwrap.dedent( + """\ + package main + + import ( + "os" + "model" + "fmt" + "encoding/json" + ) + + func main() { + objset := model.NewSHACLObjectSet() + + in_file, err := os.Open(os.Args[1]) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + defer in_file.Close() + + decoder := json.NewDecoder(in_file) + + if err := objset.Decode(decoder); err != nil { + fmt.Println(err) + os.Exit(1) + } + + out_file, err := os.Create(os.Args[2]) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + defer out_file.Close() + + encoder := json.NewEncoder(out_file) + if err := objset.Encode(encoder); err != nil { + fmt.Println(err) + os.Exit(1) + } + } + """ + ) + ) + subprocess.run(["go", "mod", "tidy"], cwd=tmp_path, check=True) + + prog = tmp_path / "roundtrip" + + subprocess.run( + ["go", "build", "-o", prog, "."], + cwd=tmp_path, + check=True, + ) + + def f(in_path, out_path): + subprocess.run( + [prog, in_path, out_path], + encoding="utf-8", + check=True, + ) + + yield f + + +def test_trailing_whitespace(): + """ + Tests that the generated file does not have trailing whitespace + """ + p = subprocess.run( + [ + "shacl2code", + "generate", + "--input", + TEST_MODEL, + "golang", + "--output", + "-", + ], + check=True, + stdout=subprocess.PIPE, + encoding="utf-8", + ) + + for num, line in enumerate(p.stdout.splitlines()): + assert ( + re.search(r"\s+$", line) is None + ), f"Line {num + 1} has trailing whitespace" + + +def test_tabs(): + """ + Tests that the output file doesn't contain tabs + """ + p = subprocess.run( + [ + "shacl2code", + "generate", + "--input", + TEST_MODEL, + "golang", + "--output", + "-", + ], + check=True, + stdout=subprocess.PIPE, + encoding="utf-8", + ) + + for num, line in enumerate(p.stdout.splitlines()): + assert "\t" not in line, f"Line {num + 1} has tabs" + + +def test_compile(compile_test): + compile_test("") + + +GO_STRING = '"string"' + + +@pytest.mark.parametrize( + "prop,value,expect", + [ + # + # positive integer + ("TestClassPositiveIntegerProp", "1", "1"), + ("TestClassPositiveIntegerProp", "-1", Progress.VALIDATION_FAILS), + ("TestClassPositiveIntegerProp", "0", Progress.VALIDATION_FAILS), + # bool is converted to integer + ("TestClassPositiveIntegerProp", "false", Progress.COMPILE_FAILS), + ("TestClassPositiveIntegerProp", "true", Progress.COMPILE_FAILS), + # Implicit conversion from double to int + ("TestClassPositiveIntegerProp", "1.0", "1"), + ("TestClassPositiveIntegerProp", "1.5", Progress.COMPILE_FAILS), + ("TestClassPositiveIntegerProp", "-1.0", Progress.VALIDATION_FAILS), + ("TestClassPositiveIntegerProp", "0.0", Progress.VALIDATION_FAILS), + # String value + ("TestClassPositiveIntegerProp", GO_STRING, Progress.COMPILE_FAILS), + # + # Non-negative integer + ("TestClassNonnegativeIntegerProp", "1", "1"), + ("TestClassNonnegativeIntegerProp", "-1", Progress.VALIDATION_FAILS), + ("TestClassNonnegativeIntegerProp", "0", "0"), + # bool is converted to integer + ("TestClassNonnegativeIntegerProp", "false", Progress.COMPILE_FAILS), + ("TestClassNonnegativeIntegerProp", "true", Progress.COMPILE_FAILS), + # Implicit conversion from double to int + ("TestClassNonnegativeIntegerProp", "1.0", "1"), + ("TestClassNonnegativeIntegerProp", "1.5", Progress.COMPILE_FAILS), + ("TestClassNonnegativeIntegerProp", "-1.0", Progress.VALIDATION_FAILS), + ("TestClassNonnegativeIntegerProp", "0.0", "0"), + # String value + ("TestClassNonnegativeIntegerProp", GO_STRING, Progress.COMPILE_FAILS), + # + # Integer + ("TestClassIntegerProp", "1", "1"), + ("TestClassIntegerProp", "-1", "-1"), + ("TestClassIntegerProp", "0", "0"), + # bool is converted to integer + ("TestClassIntegerProp", "false", Progress.COMPILE_FAILS), + ("TestClassIntegerProp", "true", Progress.COMPILE_FAILS), + # Implicit conversion from double to int + ("TestClassIntegerProp", "1.0", "1"), + ("TestClassIntegerProp", "1.5", Progress.COMPILE_FAILS), + ("TestClassIntegerProp", "-1.0", "-1"), + ("TestClassIntegerProp", "0.0", "0"), + # String value + ("TestClassIntegerProp", GO_STRING, Progress.COMPILE_FAILS), + # + # Float + ("TestClassFloatProp", "-1", "-1"), + ("TestClassFloatProp", "-1.0", "-1"), + ("TestClassFloatProp", "0", "0"), + ("TestClassFloatProp", "0.0", "0"), + ("TestClassFloatProp", "1", "1"), + ("TestClassFloatProp", "1.0", "1"), + ("TestClassFloatProp", "false", Progress.COMPILE_FAILS), + ("TestClassFloatProp", "true", Progress.COMPILE_FAILS), + # String value + ("TestClassFloatProp", GO_STRING, Progress.COMPILE_FAILS), + # + # Boolean prop + ("TestClassBooleanProp", "true", "true"), + ("TestClassBooleanProp", "1", Progress.COMPILE_FAILS), + ("TestClassBooleanProp", "-1", Progress.COMPILE_FAILS), + ("TestClassBooleanProp", "-1.0", Progress.COMPILE_FAILS), + ("TestClassBooleanProp", "false", "false"), + ("TestClassBooleanProp", "0", Progress.COMPILE_FAILS), + ("TestClassBooleanProp", "0.0", Progress.COMPILE_FAILS), + # String value + ("TestClassBooleanProp", GO_STRING, Progress.COMPILE_FAILS), + # + # String Property + ("TestClassStringScalarProp", GO_STRING, "string"), + ("TestClassStringScalarProp", '""', ""), + ("TestClassStringScalarProp", "0", Progress.COMPILE_FAILS), + ("TestClassStringScalarProp", "1", Progress.COMPILE_FAILS), + ("TestClassStringScalarProp", "1.0", Progress.COMPILE_FAILS), + ("TestClassStringScalarProp", "0.0", Progress.COMPILE_FAILS), + ("TestClassStringScalarProp", "true", Progress.COMPILE_FAILS), + ("TestClassStringScalarProp", "false", Progress.COMPILE_FAILS), + # + # Enumerated value + ( + "TestClassEnumProp", + '"http://example.org/enumType/foo"', + "http://example.org/enumType/foo", + ), + ("TestClassEnumProp", "model.EnumTypeFoo", "http://example.org/enumType/foo"), + ("TestClassEnumProp", GO_STRING, Progress.VALIDATION_FAILS), + ("TestClassEnumProp", "0", Progress.COMPILE_FAILS), + ("TestClassEnumProp", "1", Progress.COMPILE_FAILS), + ("TestClassEnumProp", "1.0", Progress.COMPILE_FAILS), + ("TestClassEnumProp", "0.0", Progress.COMPILE_FAILS), + ("TestClassEnumProp", "true", Progress.COMPILE_FAILS), + ("TestClassEnumProp", "false", Progress.COMPILE_FAILS), + # + # Pattern validated string + ("TestClassRegex", '"foo1"', "foo1"), + ("TestClassRegex", '"foo2"', "foo2"), + ("TestClassRegex", '"foo2a"', "foo2a"), + ("TestClassRegex", '"bar"', Progress.VALIDATION_FAILS), + ("TestClassRegex", '"fooa"', Progress.VALIDATION_FAILS), + ("TestClassRegex", '"afoo1"', Progress.VALIDATION_FAILS), + # + # ID assignment + ("ID", '"_:blank"', "_:blank"), + ("ID", '"http://example.com/test"', "http://example.com/test"), + ("ID", '"not-iri"', Progress.VALIDATION_FAILS), + # + ## Date Time + # ( + # "_test_class_datetimestamp_scalar_prop", + # "DateTime(0)", + # "1970-01-01T00:00:00Z", + # ), + # ( + # "_test_class_datetimestamp_scalar_prop", + # "DateTime(12345,4800)", + # "1970-01-01T03:25:45+01:20", + # ), + # ( + # "_test_class_datetimestamp_scalar_prop", + # "DateTime(12345,-4800)", + # "1970-01-01T03:25:45-01:20", + # ), + ## Implicit constructor not allowed + # ("_test_class_datetimestamp_scalar_prop", "0", Progress.COMPILE_FAILS), + # ("_test_class_datetimestamp_scalar_prop", "1.0", Progress.COMPILE_FAILS), + # ("_test_class_datetimestamp_scalar_prop", C_STRING_VAL, Progress.COMPILE_FAILS), + # ( + # "_test_class_datetimestamp_scalar_prop", + # CPP_STRING_VAL, + # Progress.COMPILE_FAILS, + # ), + ], +) +def test_scalar_prop_validation(compile_test, prop, value, expect): + output = compile_test( + f"""\ + c := model.MakeTestClass() + + // Basic assignment + err := c.{prop}().Set({value}) + if err != nil {{ + return err + }} + + fmt.Println(c.{prop}().Get()) + return nil + """, + progress=expect if isinstance(expect, Progress) else Progress.RUNS, + ) + + if isinstance(expect, Progress): + assert expect != Progress.RUNS + else: + expect_lines = [expect] + output_lines = output.splitlines() + assert ( + output_lines == expect_lines + ), f"Invalid output. Expected {expect_lines!r}, got {output_lines!r}" + + +@pytest.mark.parametrize( + "prop,value,expect", + [ + # Blank node assignment + ( + "TestClassClassProp", + 'model.MakeIRIRef[model.TestClass]("_:blank")', + "IRI _:blank", + ), + ( + "TestClassClassProp", + 'model.MakeIRIRef[model.TestClass]("http://example.com/test")', + "IRI http://example.com/test", + ), + # ( + # "TestClassClassProp", + # 'TestClassRef{}.SetIRI("not-iri")', + # Progress.VALIDATION_FAILS, + # ), + # Derived assignment + ( + "TestClassClassProp", + "model.MakeObjectRef[model.TestClass](d)", + "OBJECT _:d", + ), + # Derived conversion + ( + "TestClassClassProp", + 'convertRefUnchecked[model.TestClass](model.MakeIRIRef[model.TestDerivedClass]("_:blank"))', + "IRI _:blank", + ), + # Parent assignment + ( + "TestClassClassProp", + "model.MakeObjectRef[model.TestClass](p)", + Progress.COMPILE_FAILS, + ), + # Named individual assignment + ( + "TestClassClassProp", + "model.MakeIRIRef[model.TestClass](model.TestClassNamed)", + "IRI http://example.org/test-class/named", + ), + ## Named individual, but wrong type + # ( + # "TestClassClassProp", + # "enumType::foo", + # Progress.VALIDATION_FAILS, + # ), + # Self assignment + ( + "TestClassClassProp", + "model.MakeObjectRef[model.TestClass](c)", + "OBJECT _:c", + ), + # Self assignment (inferred generic) + ( + "TestClassClassProp", + "model.MakeObjectRef(c)", + "OBJECT _:c", + ), + # Derived assignment + ( + "TestClassClassProp", + "model.MakeObjectRef[model.TestClass](d)", + "OBJECT _:d", + ), + # Self assignment by string + ( + "TestClassClassProp", + "model.MakeIRIRef[model.TestClass](c.ID().Get())", + "IRI _:c", + ), + # Non derived class assignment + ( + "TestClassClassProp", + "model.MakeObjectRef[model.TestClass](a)", + Progress.COMPILE_FAILS, + ), + ], +) +def test_ref_prop_validation(compile_test, prop, value, expect): + output = compile_test( + f"""\ + p := model.MakeParentClass() + var err = p.ID().Set("_:p") + if err != nil {{ return err }} + + d := model.MakeTestDerivedClass() + err = d.ID().Set("_:d") + if err != nil {{ return err }} + + c := model.MakeTestClass() + err = c.ID().Set("_:c") + if err != nil {{ return err }} + + a := model.MakeTestAnotherClass() + err = a.ID().Set("_:a") + if err != nil {{ return err }} + + v := {value} + err = c.{prop}().Set(v) + if err != nil {{ return err }} + + if c.{prop}().IsObj() {{ + fmt.Println("OBJECT", c.{prop}().GetObj().ID().Get()) + }} else {{ + fmt.Println("IRI", c.{prop}().GetIRI()) + }} + """, + progress=expect if isinstance(expect, Progress) else Progress.RUNS, + ) + + if isinstance(expect, Progress): + assert expect != Progress.RUNS + else: + assert ( + output.rstrip() == expect + ), f"Bad output. Expected {expect!r}, got {output.rstrip()!r}" + + +@pytest.mark.parametrize( + "prop,value,expect", + [ + # Blank node assignment + ( + "TestClassClassProp", + '"_:blank"', + "IRI _:blank", + ), + ( + "TestClassClassProp", + '"http://example.com/test"', + "IRI http://example.com/test", + ), + # Named individual assignment + ( + "TestClassClassProp", + "model.TestClassNamed", + "IRI http://example.org/test-class/named", + ), + # Self assignment by string + ( + "TestClassClassProp", + "c.ID().Get()", + "IRI _:c", + ), + # Ref assignment + ( + "TestClassClassProp", + "model.MakeObjectRef[model.TestClass](d)", + Progress.COMPILE_FAILS, + ), + ], +) +def test_ref_prop_iri_short_validation(compile_test, prop, value, expect): + output = compile_test( + f"""\ + p := model.MakeParentClass() + var err = p.ID().Set("_:p") + if err != nil {{ return err }} + + d := model.MakeTestDerivedClass() + err = d.ID().Set("_:d") + if err != nil {{ return err }} + + c := model.MakeTestClass() + err = c.ID().Set("_:c") + if err != nil {{ return err }} + + a := model.MakeTestAnotherClass() + err = a.ID().Set("_:a") + if err != nil {{ return err }} + + v := {value} + err = c.{prop}().SetIRI(v) + if err != nil {{ return err }} + + if c.{prop}().IsObj() {{ + fmt.Println("OBJECT", c.{prop}().GetObj().ID().Get()) + }} else {{ + fmt.Println("IRI", c.{prop}().GetIRI()) + }} + """, + progress=expect if isinstance(expect, Progress) else Progress.RUNS, + ) + + if isinstance(expect, Progress): + assert expect != Progress.RUNS + else: + assert ( + output.rstrip() == expect + ), f"Bad output. Expected {expect!r}, got {output.rstrip()!r}" + + +@pytest.mark.parametrize( + "prop,value,expect", + [ + # Blank node assignment + ( + "TestClassClassProp", + '"_:blank"', + Progress.COMPILE_FAILS, + ), + # Derived assignment + ( + "TestClassClassProp", + "d", + "OBJECT _:d", + ), + # Parent assignment + ( + "TestClassClassProp", + "p", + Progress.COMPILE_FAILS, + ), + # Self assignment + ( + "TestClassClassProp", + "c", + "OBJECT _:c", + ), + # Derived assignment + ( + "TestClassClassProp", + "d", + "OBJECT _:d", + ), + # Non derived class assignment + ( + "TestClassClassProp", + "a", + Progress.COMPILE_FAILS, + ), + ], +) +def test_ref_prop_obj_short_validation(compile_test, prop, value, expect): + output = compile_test( + f"""\ + p := model.MakeParentClass() + var err = p.ID().Set("_:p") + if err != nil {{ return err }} + + d := model.MakeTestDerivedClass() + err = d.ID().Set("_:d") + if err != nil {{ return err }} + + c := model.MakeTestClass() + err = c.ID().Set("_:c") + if err != nil {{ return err }} + + a := model.MakeTestAnotherClass() + err = a.ID().Set("_:a") + if err != nil {{ return err }} + + v := {value} + err = c.{prop}().SetObj(v) + if err != nil {{ return err }} + + if c.{prop}().IsObj() {{ + fmt.Println("OBJECT", c.{prop}().GetObj().ID().Get()) + }} else {{ + fmt.Println("IRI", c.{prop}().GetIRI()) + }} + """, + progress=expect if isinstance(expect, Progress) else Progress.RUNS, + ) + + if isinstance(expect, Progress): + assert expect != Progress.RUNS + else: + assert ( + output.rstrip() == expect + ), f"Bad output. Expected {expect!r}, got {output.rstrip()!r}" + + +def test_roundtrip(tmp_path, roundtrip, roundtrip_test): + out_file = tmp_path / "out.json" + + roundtrip_test(roundtrip, out_file) + + with roundtrip.open("r") as f: + expect = json.load(f) + + with out_file.open("r") as f: + actual = json.load(f) + + assert expect == actual + + +@jsonvalidation.validation_tests() +def test_json_validation(passes, data, tmp_path, test_context_url, validate_test): + jsonvalidation.replace_context(data, test_context_url) + + data_file = tmp_path / "data.json" + data_file.write_text(json.dumps(data)) + + validate_test(data_file, passes) + + +@jsonvalidation.type_tests() +def test_json_types(passes, data, tmp_path, test_context_url, validate_test): + jsonvalidation.replace_context(data, test_context_url) + + data_file = tmp_path / "data.json" + data_file.write_text(json.dumps(data)) + + validate_test(data_file, passes)