Skip to content

Commit

Permalink
Propagate noLinkCheck through maps and records
Browse files Browse the repository at this point in the history
  • Loading branch information
GlassOfWhiskey committed Nov 22, 2023
1 parent d3b849b commit bc718b6
Show file tree
Hide file tree
Showing 14 changed files with 148 additions and 72 deletions.
17 changes: 10 additions & 7 deletions schema_salad/codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,10 @@ def codegen(
for rec in j:
if rec["type"] in ("enum", "map", "record", "union"):
jld = rec.get("jsonldPredicate")
container = jld.get("_container") if isinstance(jld, MutableMapping) else None
gen.type_loader(rec, container)
if isinstance(jld, MutableMapping):
gen.type_loader(rec, jld.get("_container"), jld.get("noLinkCheck"))
else:
gen.type_loader(rec)
gen.add_vocab(shortname(rec["name"]), rec["name"])

for rec in j:
Expand Down Expand Up @@ -166,9 +168,7 @@ def codegen(
subscope = field.get("subscope")
fieldpred = field["name"]
optional = bool("https://w3id.org/cwl/salad#null" in field["type"])
uri_loader = gen.uri_loader(
gen.type_loader(field["type"]), True, False, None, None
)
uri_loader = gen.uri_loader(gen.type_loader(field["type"]), True, False, None)
gen.declare_id_field(
fieldpred,
uri_loader,
Expand All @@ -180,12 +180,13 @@ def codegen(
for field in sorted_fields:
optional = bool("https://w3id.org/cwl/salad#null" in field["type"])
jld = field.get("jsonldPredicate")
container = jld.get("_container") if isinstance(jld, MutableMapping) else None
type_loader = gen.type_loader(field["type"], container)
fieldpred = field["name"]
subscope = None

if isinstance(jld, MutableMapping):
type_loader = gen.type_loader(
field["type"], jld.get("_container"), jld.get("noLinkCheck")
)
ref_scope = jld.get("refScope")
subscope = jld.get("subscope")
if jld.get("typeDSL"):
Expand Down Expand Up @@ -216,6 +217,8 @@ def codegen(

if "_id" in jld and jld["_id"][0] != "@":
fieldpred = jld["_id"]
else:
type_loader = gen.type_loader(field["type"])

if jld == "@id":
continue
Expand Down
7 changes: 5 additions & 2 deletions schema_salad/codegen_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,10 @@ def end_class(self, classname: str, field_names: List[str]) -> None:
raise NotImplementedError()

def type_loader(
self, type_declaration: Union[List[Any], Dict[str, Any]], container: Optional[str] = None
self,
type_declaration: Union[List[Any], Dict[str, Any]],
container: Optional[str] = None,
no_link_check: Optional[bool] = None,
) -> TypeDef:
"""Parse the given type declaration and declare its components."""
raise NotImplementedError()
Expand Down Expand Up @@ -140,7 +143,7 @@ def uri_loader(
scoped_id: bool,
vocab_term: bool,
ref_scope: Optional[int],
no_link_check: Optional[bool],
no_link_check: Optional[bool] = None,
) -> TypeDef:
"""Construct the TypeDef for the given URI loader."""
raise NotImplementedError()
Expand Down
8 changes: 5 additions & 3 deletions schema_salad/dotnet/util/Loaders/MapLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ internal class MapLoader<T> : ILoader<Dictionary<string, T>>
{
private readonly ILoader valueLoader;
private readonly string? container;
private readonly bool? noLinkCheck;

public MapLoader(in ILoader valueLoader, in string? container)
public MapLoader(in ILoader valueLoader, in string? container, in bool? noLinkCheck)
{
this.valueLoader = valueLoader;
this.container = container;
this.noLinkCheck = noLinkCheck;
}

public Dictionary<string, T> Load(in object doc, in string baseuri, in LoadingOptions loadingOptions, in string? docRoot = null)
Expand All @@ -26,9 +28,9 @@ public Dictionary<string, T> Load(in object doc, in string baseuri, in LoadingOp
}

LoadingOptions innerLoadingOptions = loadingOptions;
if (this.container != null)
if (this.container != null || this.noLinkCheck != null)
{
innerLoadingOptions = new LoadingOptions(copyFrom: loadingOptions, container: this.container);
innerLoadingOptions = new LoadingOptions(copyFrom: loadingOptions, container: this.container, noLinkCheck: this.noLinkCheck);
}

IDictionary docDictionary = (IDictionary)doc;
Expand Down
8 changes: 5 additions & 3 deletions schema_salad/dotnet/util/Loaders/RecordLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ namespace ${project_name};
internal class RecordLoader<T> : ILoader<T> where T : ISaveable
{
private readonly string? container;
private readonly bool? noLinkCheck;

public RecordLoader(in string? container)
public RecordLoader(in string? container, in bool? noLinkCheck)
{
this.container = container;
this.noLinkCheck = noLinkCheck;
}

public T Load(in object doc, in string baseUri, in LoadingOptions loadingOptions, in string? docRoot = null)
Expand All @@ -19,9 +21,9 @@ public T Load(in object doc, in string baseUri, in LoadingOptions loadingOptions
}

LoadingOptions innerLoadingOptions = loadingOptions;
if (this.container != null)
if (this.container != null || this.noLinkCheck != null)
{
innerLoadingOptions = new LoadingOptions(copyFrom: loadingOptions, container: this.container);
innerLoadingOptions = new LoadingOptions(copyFrom: loadingOptions, container: this.container, noLinkCheck: this.noLinkCheck);
}

return (T)T.FromDoc(doc, baseUri, innerLoadingOptions, docRoot);
Expand Down
9 changes: 6 additions & 3 deletions schema_salad/dotnet_codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ def type_loader(
self,
type_declaration: Union[List[Any], Dict[str, Any], str],
container: Optional[str] = None,
no_link_check: Optional[bool] = None,
) -> TypeDef:
"""Parse the given type declaration and declare its components."""
if isinstance(type_declaration, MutableSequence):
Expand Down Expand Up @@ -438,10 +439,11 @@ def type_loader(
instance_type=f"Dictionary<string, {i.instance_type}>",
name=f"map_of_{i.name}",
loader_type=f"ILoader<Dictionary<string, {i.instance_type}>>",
init="new MapLoader<{}>({}, {})".format(
init="new MapLoader<{}>({}, {}, {})".format(
i.instance_type,
i.name,
f"'{container}'" if container is not None else None,
self.to_dotnet(no_link_check),
),
)
)
Expand All @@ -455,9 +457,10 @@ def type_loader(
TypeDef(
instance_type=self.safe_name(type_declaration["name"]),
name=self.safe_name(type_declaration["name"]) + "Loader",
init="new RecordLoader<{}>({})".format(
init="new RecordLoader<{}>({}, {})".format(
self.safe_name(type_declaration["name"]),
f"'{container}'" if container is not None else None,
self.to_dotnet(no_link_check),
),
loader_type="ILoader<{}>".format(self.safe_name(type_declaration["name"])),
abstract=type_declaration.get("abstract", False),
Expand Down Expand Up @@ -839,7 +842,7 @@ def uri_loader(
scoped_id: bool,
vocab_term: bool,
ref_scope: Optional[int],
no_link_check: Optional[bool],
no_link_check: Optional[bool] = None,
) -> TypeDef:
"""Construct the TypeDef for the given URI loader."""
instance_type = inner.instance_type or "object"
Expand Down
15 changes: 12 additions & 3 deletions schema_salad/java/main_utils/MapLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@
public class MapLoader<T> implements Loader<Map<String, T>> {
private final Loader<T> valueLoader;
private final String container;
private final Boolean noLinkCheck;

public MapLoader(Loader<T> valueLoader, String container) {
public MapLoader(Loader<T> valueLoader, final String container, final Boolean noLinkCheck) {
this.valueLoader = valueLoader;
this.container = container;
this.noLinkCheck = noLinkCheck;
}

public Map<String, T> load(
Expand All @@ -21,8 +23,15 @@ public Map<String, T> load(
final String docRoot) {
final Map<String, Object> docMap = (Map<String, Object>) Loader.validateOfJavaType(Map.class, doc);
LoadingOptions innerLoadingOptions = loadingOptions;
if (this.container != null) {
innerLoadingOptions = new LoadingOptionsBuilder().copiedFrom(loadingOptions).setContainer(this.container).build();
if (this.container != null || this.noLinkCheck != null) {
LoadingOptionsBuilder builder = new LoadingOptionsBuilder().copiedFrom(loadingOptions);
if (this.container != null) {
builder.setContainer(this.container);
}
if (this.noLinkCheck != null) {
builder.setNoLinkCheck(this.noLinkCheck);
}
innerLoadingOptions = builder.build();
}
final Map<String, T> r = new HashMap();
final List<ValidationException> errors = new ArrayList();
Expand Down
15 changes: 12 additions & 3 deletions schema_salad/java/main_utils/RecordLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
public class RecordLoader<T extends Saveable> implements Loader<T> {
private final Class<? extends T> saveableClass;
private final String container;
private final Boolean noLinkCheck;

public RecordLoader(final Class<? extends T> saveableClass, final String container) {
public RecordLoader(final Class<? extends T> saveableClass, final String container, final Boolean noLinkCheck) {
this.saveableClass = saveableClass;
this.container = container;
this.noLinkCheck = noLinkCheck;
}

public T load(
Expand All @@ -23,8 +25,15 @@ public T load(
this.saveableClass.getConstructor(
new Class[] {Object.class, String.class, LoadingOptions.class, String.class});
LoadingOptions innerLoadingOptions = loadingOptions;
if (this.container != null) {
innerLoadingOptions = new LoadingOptionsBuilder().copiedFrom(loadingOptions).setContainer(this.container).build();
if (this.container != null || this.noLinkCheck != null) {
LoadingOptionsBuilder builder = new LoadingOptionsBuilder().copiedFrom(loadingOptions);
if (this.container != null) {
builder.setContainer(this.container);
}
if (this.noLinkCheck != null) {
builder.setNoLinkCheck(this.noLinkCheck);
}
innerLoadingOptions = builder.build();
}
final T ret = constructor.newInstance(doc, baseUri, innerLoadingOptions, docRoot);
return ret;
Expand Down
13 changes: 9 additions & 4 deletions schema_salad/java_codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,7 @@ def type_loader(
self,
type_declaration: Union[List[Any], Dict[str, Any], str],
container: Optional[str] = None,
no_link_check: Optional[bool] = None,
) -> TypeDef:
"""Parse the given type declaration and declare its components."""
if isinstance(type_declaration, MutableSequence):
Expand Down Expand Up @@ -468,8 +469,10 @@ def type_loader(
# instance_type="Map<String, {}>".format(i.instance_type),
instance_type=f"java.util.Map<String, {i.instance_type}>",
name=f"map_of_{i.name}",
init="new MapLoader({}, {})".format(
i.name, f"'{container}'" if container is not None else None
init="new MapLoader({}, {}, {})".format(
i.name,
f"'{container}'" if container is not None else None,
self.to_java(no_link_check),
),
loader_type=f"Loader<java.util.Map<String, {i.instance_type}>>",
)
Expand All @@ -486,10 +489,12 @@ def type_loader(
TypeDef(
instance_type=self.safe_name(type_declaration["name"]),
name=self.safe_name(type_declaration["name"]),
init="new RecordLoader<{clazz}>({clazz}{ext}.class, {container})".format(
init="new RecordLoader<{clazz}>({clazz}{ext}.class, "
"{container}, {no_link_check})".format(
clazz=fqclass,
ext="Impl" if not is_abstract else "",
container=f"'{container}'" if container is not None else None,
no_link_check=self.to_java(no_link_check),
),
loader_type=f"Loader<{fqclass}>",
)
Expand Down Expand Up @@ -805,7 +810,7 @@ def uri_loader(
scoped_id: bool,
vocab_term: bool,
ref_scope: Optional[int],
no_link_check: Optional[bool],
no_link_check: Optional[bool] = None,
) -> TypeDef:
instance_type = inner.instance_type or "Object"
return self.declare_type(
Expand Down
55 changes: 35 additions & 20 deletions schema_salad/metaschema.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,11 +530,16 @@ def __repr__(self) -> str:

class _MapLoader(_Loader):
def __init__(
self, values: _Loader, name: Optional[str] = None, container: Optional[str] = None
self,
values: _Loader,
name: Optional[str] = None,
container: Optional[str] = None,
no_link_check: Optional[bool] = None,
) -> None:
self.values = values
self.name = name
self.container = container
self.no_link_check = no_link_check

def load(
self,
Expand All @@ -546,8 +551,10 @@ def load(
) -> Any:
if not isinstance(doc, MutableMapping):
raise ValidationException(f"Expected a map, was {type(doc)}")
if self.container is not None:
loadingOptions = LoadingOptions(copyfrom=loadingOptions, container=self.container)
if self.container is not None or self.no_link_check is not None:
loadingOptions = LoadingOptions(
copyfrom=loadingOptions, container=self.container, no_link_check=self.no_link_check
)
r: Dict[str, Any] = {}
errors: List[SchemaSaladException] = []
for k, v in doc.items():
Expand Down Expand Up @@ -658,9 +665,15 @@ def load(


class _RecordLoader(_Loader):
def __init__(self, classtype: Type[Saveable], container: Optional[str] = None) -> None:
def __init__(
self,
classtype: Type[Saveable],
container: Optional[str] = None,
no_link_check: Optional[bool] = None,
) -> None:
self.classtype = classtype
self.container = container
self.no_link_check = no_link_check

def load(
self,
Expand All @@ -675,8 +688,10 @@ def load(
f"Value is a {convert_typing(extract_type(type(doc)))}, "
f"but valid type for this field is an object."
)
if self.container is not None:
loadingOptions = LoadingOptions(copyfrom=loadingOptions, container=self.container)
if self.container is not None or self.no_link_check is not None:
loadingOptions = LoadingOptions(
copyfrom=loadingOptions, container=self.container, no_link_check=self.no_link_check
)
return self.classtype.fromDoc(doc, baseuri, loadingOptions, docRoot=docRoot)

def __repr__(self) -> str:
Expand Down Expand Up @@ -6924,20 +6939,20 @@ def save(
"""
The **Any** type validates for any non-null value.
"""
RecordFieldLoader = _RecordLoader(RecordField, None)
RecordSchemaLoader = _RecordLoader(RecordSchema, None)
EnumSchemaLoader = _RecordLoader(EnumSchema, None)
ArraySchemaLoader = _RecordLoader(ArraySchema, None)
MapSchemaLoader = _RecordLoader(MapSchema, None)
UnionSchemaLoader = _RecordLoader(UnionSchema, None)
JsonldPredicateLoader = _RecordLoader(JsonldPredicate, None)
SpecializeDefLoader = _RecordLoader(SpecializeDef, None)
SaladRecordFieldLoader = _RecordLoader(SaladRecordField, None)
SaladRecordSchemaLoader = _RecordLoader(SaladRecordSchema, None)
SaladEnumSchemaLoader = _RecordLoader(SaladEnumSchema, None)
SaladMapSchemaLoader = _RecordLoader(SaladMapSchema, None)
SaladUnionSchemaLoader = _RecordLoader(SaladUnionSchema, None)
DocumentationLoader = _RecordLoader(Documentation, None)
RecordFieldLoader = _RecordLoader(RecordField, None, None)
RecordSchemaLoader = _RecordLoader(RecordSchema, None, None)
EnumSchemaLoader = _RecordLoader(EnumSchema, None, None)
ArraySchemaLoader = _RecordLoader(ArraySchema, None, None)
MapSchemaLoader = _RecordLoader(MapSchema, None, None)
UnionSchemaLoader = _RecordLoader(UnionSchema, None, None)
JsonldPredicateLoader = _RecordLoader(JsonldPredicate, None, None)
SpecializeDefLoader = _RecordLoader(SpecializeDef, None, None)
SaladRecordFieldLoader = _RecordLoader(SaladRecordField, None, None)
SaladRecordSchemaLoader = _RecordLoader(SaladRecordSchema, None, None)
SaladEnumSchemaLoader = _RecordLoader(SaladEnumSchema, None, None)
SaladMapSchemaLoader = _RecordLoader(SaladMapSchema, None, None)
SaladUnionSchemaLoader = _RecordLoader(SaladUnionSchema, None, None)
DocumentationLoader = _RecordLoader(Documentation, None, None)
array_of_strtype = _ArrayLoader(strtype)
union_of_None_type_or_strtype_or_array_of_strtype = _UnionLoader(
(
Expand Down
Loading

0 comments on commit bc718b6

Please sign in to comment.