File Index
Files and directories
Sign in
FILE

program.py

File preview with syntax highlighting.

linux-6.19.14/tools/net/sunrpc/xdrgen/generators/program.py PYTHON
  1#!/usr/bin/env python3
  2# ex: set filetype=python:
  3
  4"""Generate code for an RPC program's procedures"""
  5
  6from jinja2 import Environment
  7
  8from generators import SourceGenerator, create_jinja2_environment
  9from xdr_ast import _RpcProgram, _RpcVersion, excluded_apis
 10
 11
 12def emit_version_definitions(
 13    environment: Environment, program: str, version: _RpcVersion
 14) -> None:
 15    """Emit procedure numbers for each RPC version's procedures"""
 16    template = environment.get_template("definition/open.j2")
 17    print(template.render(program=program.upper()))
 18
 19    template = environment.get_template("definition/procedure.j2")
 20    for procedure in version.procedures:
 21        if procedure.name not in excluded_apis:
 22            print(
 23                template.render(
 24                    name=procedure.name,
 25                    value=procedure.number,
 26                )
 27            )
 28
 29    template = environment.get_template("definition/close.j2")
 30    print(template.render())
 31
 32
 33def emit_version_declarations(
 34    environment: Environment, program: str, version: _RpcVersion
 35) -> None:
 36    """Emit declarations for each RPC version's procedures"""
 37    arguments = dict.fromkeys([])
 38    for procedure in version.procedures:
 39        if procedure.name not in excluded_apis:
 40            arguments[procedure.argument.type_name] = None
 41    if len(arguments) > 0:
 42        print("")
 43        template = environment.get_template("declaration/argument.j2")
 44        for argument in arguments:
 45            print(template.render(program=program, argument=argument))
 46
 47    results = dict.fromkeys([])
 48    for procedure in version.procedures:
 49        if procedure.name not in excluded_apis:
 50            results[procedure.result.type_name] = None
 51    if len(results) > 0:
 52        print("")
 53        template = environment.get_template("declaration/result.j2")
 54        for result in results:
 55            print(template.render(program=program, result=result))
 56
 57
 58def emit_version_argument_decoders(
 59    environment: Environment, program: str, version: _RpcVersion
 60) -> None:
 61    """Emit server argument decoders for each RPC version's procedures"""
 62    arguments = dict.fromkeys([])
 63    for procedure in version.procedures:
 64        if procedure.name not in excluded_apis:
 65            arguments[procedure.argument.type_name] = None
 66
 67    template = environment.get_template("decoder/argument.j2")
 68    for argument in arguments:
 69        print(template.render(program=program, argument=argument))
 70
 71
 72def emit_version_result_decoders(
 73    environment: Environment, program: str, version: _RpcVersion
 74) -> None:
 75    """Emit client result decoders for each RPC version's procedures"""
 76    results = dict.fromkeys([])
 77    for procedure in version.procedures:
 78        if procedure.name not in excluded_apis:
 79            results[procedure.result.type_name] = None
 80
 81    template = environment.get_template("decoder/result.j2")
 82    for result in results:
 83        print(template.render(program=program, result=result))
 84
 85
 86def emit_version_argument_encoders(
 87    environment: Environment, program: str, version: _RpcVersion
 88) -> None:
 89    """Emit client argument encoders for each RPC version's procedures"""
 90    arguments = dict.fromkeys([])
 91    for procedure in version.procedures:
 92        if procedure.name not in excluded_apis:
 93            arguments[procedure.argument.type_name] = None
 94
 95    template = environment.get_template("encoder/argument.j2")
 96    for argument in arguments:
 97        print(template.render(program=program, argument=argument))
 98
 99
100def emit_version_result_encoders(
101    environment: Environment, program: str, version: _RpcVersion
102) -> None:
103    """Emit server result encoders for each RPC version's procedures"""
104    results = dict.fromkeys([])
105    for procedure in version.procedures:
106        if procedure.name not in excluded_apis:
107            results[procedure.result.type_name] = None
108
109    template = environment.get_template("encoder/result.j2")
110    for result in results:
111        print(template.render(program=program, result=result))
112
113
114class XdrProgramGenerator(SourceGenerator):
115    """Generate source code for an RPC program's procedures"""
116
117    def __init__(self, language: str, peer: str):
118        """Initialize an instance of this class"""
119        self.environment = create_jinja2_environment(language, "program")
120        self.peer = peer
121
122    def emit_definition(self, node: _RpcProgram) -> None:
123        """Emit procedure numbers for each of an RPC programs's procedures"""
124        raw_name = node.name
125        program = raw_name.lower().removesuffix("_program").removesuffix("_prog")
126
127        for version in node.versions:
128            emit_version_definitions(self.environment, program, version)
129
130    def emit_declaration(self, node: _RpcProgram) -> None:
131        """Emit a declaration pair for each of an RPC programs's procedures"""
132        raw_name = node.name
133        program = raw_name.lower().removesuffix("_program").removesuffix("_prog")
134
135        for version in node.versions:
136            emit_version_declarations(self.environment, program, version)
137
138    def emit_decoder(self, node: _RpcProgram) -> None:
139        """Emit all decoder functions for an RPC program's procedures"""
140        raw_name = node.name
141        program = raw_name.lower().removesuffix("_program").removesuffix("_prog")
142        match self.peer:
143            case "server":
144                for version in node.versions:
145                    emit_version_argument_decoders(
146                        self.environment, program, version,
147                    )
148            case "client":
149                for version in node.versions:
150                    emit_version_result_decoders(
151                        self.environment, program, version,
152                    )
153
154    def emit_encoder(self, node: _RpcProgram) -> None:
155        """Emit all encoder functions for an RPC program's procedures"""
156        raw_name = node.name
157        program = raw_name.lower().removesuffix("_program").removesuffix("_prog")
158        match self.peer:
159            case "server":
160                for version in node.versions:
161                    emit_version_result_encoders(
162                        self.environment, program, version,
163                    )
164            case "client":
165                for version in node.versions:
166                    emit_version_argument_encoders(
167                        self.environment, program, version,
168                    )
~/ Read-only file preview.