comparison env/lib/python3.9/site-packages/schema_salad/codegen.py @ 0:4f3585e2f14b draft default tip

"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author shellac
date Mon, 22 Mar 2021 18:12:50 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4f3585e2f14b
1 """Generate langauge specific loaders for a particular SALAD schema."""
2 import sys
3 from io import TextIOWrapper
4 from typing import (
5 Any,
6 Dict,
7 List,
8 MutableMapping,
9 MutableSequence,
10 Optional,
11 TextIO,
12 Union,
13 )
14
15 from . import schema
16 from .codegen_base import CodeGenBase
17 from .exceptions import SchemaSaladException
18 from .java_codegen import JavaCodeGen
19 from .python_codegen import PythonCodeGen
20 from .ref_resolver import Loader
21 from .schema import shortname
22 from .utils import aslist
23
24
25 def codegen(
26 lang: str,
27 i: List[Dict[str, str]],
28 schema_metadata: Dict[str, Any],
29 loader: Loader,
30 target: Optional[str] = None,
31 examples: Optional[str] = None,
32 package: Optional[str] = None,
33 copyright: Optional[str] = None,
34 ) -> None:
35 """Generate classes with loaders for the given Schema Salad description."""
36
37 j = schema.extend_and_specialize(i, loader)
38
39 gen = None # type: Optional[CodeGenBase]
40 if lang == "python":
41 if target:
42 dest: Union[TextIOWrapper, TextIO] = open(
43 target, mode="w", encoding="utf-8"
44 )
45 else:
46 dest = sys.stdout
47 gen = PythonCodeGen(dest, copyright=copyright)
48 elif lang == "java":
49 gen = JavaCodeGen(
50 schema_metadata.get("$base", schema_metadata.get("id")),
51 target=target,
52 examples=examples,
53 package=package,
54 copyright=copyright,
55 )
56 else:
57 raise SchemaSaladException(f"Unsupported code generation language '{lang}'")
58
59 gen.prologue()
60
61 document_roots = []
62
63 for rec in j:
64 if rec["type"] in ("enum", "record"):
65 gen.type_loader(rec)
66 gen.add_vocab(shortname(rec["name"]), rec["name"])
67
68 for rec in j:
69 if rec["type"] == "enum":
70 for symbol in rec["symbols"]:
71 gen.add_vocab(shortname(symbol), symbol)
72
73 if rec["type"] == "record":
74 if rec.get("documentRoot"):
75 document_roots.append(rec["name"])
76
77 field_names = []
78 optional_fields = set()
79 for field in rec.get("fields", []):
80 field_name = shortname(field["name"])
81 field_names.append(field_name)
82 tp = field["type"]
83 if (
84 isinstance(tp, MutableSequence)
85 and tp[0] == "https://w3id.org/cwl/salad#null"
86 ):
87 optional_fields.add(field_name)
88
89 idfield = ""
90 for field in rec.get("fields", []):
91 if field.get("jsonldPredicate") == "@id":
92 idfield = field.get("name")
93
94 gen.begin_class(
95 rec["name"],
96 aslist(rec.get("extends", [])),
97 rec.get("doc", ""),
98 rec.get("abstract", False),
99 field_names,
100 idfield,
101 optional_fields,
102 )
103 gen.add_vocab(shortname(rec["name"]), rec["name"])
104
105 for field in rec.get("fields", []):
106 if field.get("jsonldPredicate") == "@id":
107 subscope = field.get("subscope")
108 fieldpred = field["name"]
109 optional = bool("https://w3id.org/cwl/salad#null" in field["type"])
110 uri_loader = gen.uri_loader(
111 gen.type_loader(field["type"]), True, False, None
112 )
113 gen.declare_id_field(
114 fieldpred, uri_loader, field.get("doc"), optional, subscope
115 )
116 break
117
118 for field in rec.get("fields", []):
119 optional = bool("https://w3id.org/cwl/salad#null" in field["type"])
120 type_loader = gen.type_loader(field["type"])
121 jld = field.get("jsonldPredicate")
122 fieldpred = field["name"]
123 subscope = None
124
125 if isinstance(jld, MutableMapping):
126 ref_scope = jld.get("refScope")
127 if jld.get("typeDSL"):
128 type_loader = gen.typedsl_loader(type_loader, ref_scope)
129 elif jld.get("secondaryFilesDSL"):
130 type_loader = gen.secondaryfilesdsl_loader(type_loader)
131 elif jld.get("subscope"):
132 subscope = jld.get("subscope")
133 elif jld.get("_type") == "@id":
134 type_loader = gen.uri_loader(
135 type_loader, jld.get("identity", False), False, ref_scope
136 )
137 elif jld.get("_type") == "@vocab":
138 type_loader = gen.uri_loader(
139 type_loader, False, True, ref_scope
140 )
141
142 map_subject = jld.get("mapSubject")
143 if map_subject:
144 type_loader = gen.idmap_loader(
145 field["name"],
146 type_loader,
147 map_subject,
148 jld.get("mapPredicate"),
149 )
150
151 if "_id" in jld and jld["_id"][0] != "@":
152 fieldpred = jld["_id"]
153
154 if jld == "@id":
155 continue
156
157 gen.declare_field(fieldpred, type_loader, field.get("doc"), optional)
158
159 gen.end_class(rec["name"], field_names)
160
161 root_type = list(document_roots)
162 root_type.append({"type": "array", "items": document_roots})
163
164 gen.epilogue(gen.type_loader(root_type))