comparison env/lib/python3.7/site-packages/schema_salad/codegen.py @ 0:26e78fe6e8c4 draft

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