File: codegen_base.py

package info (click to toggle)
python-schema-salad 3.0.20181206233650-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 3,904 kB
  • sloc: python: 6,672; makefile: 181; sh: 6
file content (100 lines) | stat: -rw-r--r-- 4,248 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
"""Base class for the generation of loaders from schema-salad definitions."""
import collections
from typing import (Any, Dict, List, MutableSequence, Optional, Union)

from typing_extensions import Text  # pylint: disable=unused-import
# move to a regular typing import when Python 3.3-3.6 is no longer supported

from . import schema

class TypeDef(object):  # pylint: disable=too-few-public-methods
    """Schema Salad type description."""
    # switch to class-style typing.NamedTuple once support for Python < 3.6
    # is dropped
    def __init__(self,  # pylint: disable=too-many-arguments
                 name,             # type: Text
                 init,             # type: Text
                 is_uri=False,     # type: bool
                 scoped_id=False,  # type: bool
                 ref_scope=0       # type: Optional[int]
                ):  # type: (...) -> None
        self.name = name
        self.init = init
        self.is_uri = is_uri
        self.scoped_id = scoped_id
        self.ref_scope = ref_scope

class CodeGenBase(object):
    """Abstract base class for schema salad code generators."""
    def __init__(self):  # type: () -> None
        self.collected_types = collections.OrderedDict()  # type: collections.OrderedDict[Text, TypeDef]
        self.vocab = {}  # type: Dict[Text, Text]

    def declare_type(self, declared_type):  # type: (TypeDef) -> TypeDef
        """Add this type to our collection, if needed."""
        if declared_type not in self.collected_types:
            self.collected_types[declared_type.name] = declared_type
        return declared_type

    def add_vocab(self, name, uri):  # type: (Text, Text) -> None
        """Add the given name as an abbreviation for the given URI."""
        self.vocab[name] = uri

    def prologue(self):  # type: () -> None
        """Trigger to generate the prolouge code."""
        raise NotImplementedError()

    @staticmethod
    def safe_name(name):  # type: (Text) -> Text
        """Generate a safe version of the given name."""
        return schema.avro_name(name)

    def begin_class(self,  # pylint: disable=too-many-arguments
                    classname,    # type: Text
                    extends,      # type: MutableSequence[Text]
                    doc,          # type: Text
                    abstract,     # type: bool
                    field_names,  # type: MutableSequence[Text]
                    idfield       # type: Text
                   ):  # type: (...) -> None
        """Produce the header for the given class."""
        raise NotImplementedError()

    def end_class(self, classname, field_names):
        # type: (Text, List[Text]) -> None
        """Signal that we are done with this class."""
        raise NotImplementedError()

    def type_loader(self, type_declaration):
        # type: (Union[List[Any], Dict[Text, Any]]) -> TypeDef
        """Parse the given type declaration and declare its components."""
        raise NotImplementedError()

    def declare_field(self, name, fieldtype, doc, optional):
        # type: (Text, TypeDef, Text, bool) -> None
        """Output the code to load the given field."""
        raise NotImplementedError()

    def declare_id_field(self, name, fieldtype, doc, optional):
        # type: (Text, TypeDef, Text, bool) -> None
        """Output the code to handle the given ID field."""
        raise NotImplementedError()

    def uri_loader(self, inner, scoped_id, vocab_term, ref_scope):
        # type: (TypeDef, bool, bool, Union[int, None]) -> TypeDef
        """Construct the TypeDef for the given URI loader."""
        raise NotImplementedError()

    def idmap_loader(self, field, inner, map_subject, map_predicate):
        # type: (Text, TypeDef, Text, Union[Text, None]) -> TypeDef
        """Construct the TypeDef for the given mapped ID loader."""
        raise NotImplementedError()

    def typedsl_loader(self, inner, ref_scope):
        # type: (TypeDef, Union[int, None]) -> TypeDef
        """Construct the TypeDef for the given DSL loader."""
        raise NotImplementedError()

    def epilogue(self, root_loader):  # type: (TypeDef) -> None
        """Trigger to generate the epilouge code."""
        raise NotImplementedError()