Path: blob/master/tools/net/sunrpc/xdrgen/generators/program.py
26292 views
#!/usr/bin/env python31# ex: set filetype=python:23"""Generate code for an RPC program's procedures"""45from jinja2 import Environment67from generators import SourceGenerator, create_jinja2_environment8from xdr_ast import _RpcProgram, _RpcVersion, excluded_apis91011def emit_version_definitions(12environment: Environment, program: str, version: _RpcVersion13) -> None:14"""Emit procedure numbers for each RPC version's procedures"""15template = environment.get_template("definition/open.j2")16print(template.render(program=program.upper()))1718template = environment.get_template("definition/procedure.j2")19for procedure in version.procedures:20if procedure.name not in excluded_apis:21print(22template.render(23name=procedure.name,24value=procedure.number,25)26)2728template = environment.get_template("definition/close.j2")29print(template.render())303132def emit_version_declarations(33environment: Environment, program: str, version: _RpcVersion34) -> None:35"""Emit declarations for each RPC version's procedures"""36arguments = dict.fromkeys([])37for procedure in version.procedures:38if procedure.name not in excluded_apis:39arguments[procedure.argument.type_name] = None40if len(arguments) > 0:41print("")42template = environment.get_template("declaration/argument.j2")43for argument in arguments:44print(template.render(program=program, argument=argument))4546results = dict.fromkeys([])47for procedure in version.procedures:48if procedure.name not in excluded_apis:49results[procedure.result.type_name] = None50if len(results) > 0:51print("")52template = environment.get_template("declaration/result.j2")53for result in results:54print(template.render(program=program, result=result))555657def emit_version_argument_decoders(58environment: Environment, program: str, version: _RpcVersion59) -> None:60"""Emit server argument decoders for each RPC version's procedures"""61arguments = dict.fromkeys([])62for procedure in version.procedures:63if procedure.name not in excluded_apis:64arguments[procedure.argument.type_name] = None6566template = environment.get_template("decoder/argument.j2")67for argument in arguments:68print(template.render(program=program, argument=argument))697071def emit_version_result_decoders(72environment: Environment, program: str, version: _RpcVersion73) -> None:74"""Emit client result decoders for each RPC version's procedures"""75results = dict.fromkeys([])76for procedure in version.procedures:77if procedure.name not in excluded_apis:78results[procedure.result.type_name] = None7980template = environment.get_template("decoder/result.j2")81for result in results:82print(template.render(program=program, result=result))838485def emit_version_argument_encoders(86environment: Environment, program: str, version: _RpcVersion87) -> None:88"""Emit client argument encoders for each RPC version's procedures"""89arguments = dict.fromkeys([])90for procedure in version.procedures:91if procedure.name not in excluded_apis:92arguments[procedure.argument.type_name] = None9394template = environment.get_template("encoder/argument.j2")95for argument in arguments:96print(template.render(program=program, argument=argument))979899def emit_version_result_encoders(100environment: Environment, program: str, version: _RpcVersion101) -> None:102"""Emit server result encoders for each RPC version's procedures"""103results = dict.fromkeys([])104for procedure in version.procedures:105if procedure.name not in excluded_apis:106results[procedure.result.type_name] = None107108template = environment.get_template("encoder/result.j2")109for result in results:110print(template.render(program=program, result=result))111112113class XdrProgramGenerator(SourceGenerator):114"""Generate source code for an RPC program's procedures"""115116def __init__(self, language: str, peer: str):117"""Initialize an instance of this class"""118self.environment = create_jinja2_environment(language, "program")119self.peer = peer120121def emit_definition(self, node: _RpcProgram) -> None:122"""Emit procedure numbers for each of an RPC programs's procedures"""123raw_name = node.name124program = raw_name.lower().removesuffix("_program").removesuffix("_prog")125126for version in node.versions:127emit_version_definitions(self.environment, program, version)128129def emit_declaration(self, node: _RpcProgram) -> None:130"""Emit a declaration pair for each of an RPC programs's procedures"""131raw_name = node.name132program = raw_name.lower().removesuffix("_program").removesuffix("_prog")133134for version in node.versions:135emit_version_declarations(self.environment, program, version)136137def emit_decoder(self, node: _RpcProgram) -> None:138"""Emit all decoder functions for an RPC program's procedures"""139raw_name = node.name140program = raw_name.lower().removesuffix("_program").removesuffix("_prog")141match self.peer:142case "server":143for version in node.versions:144emit_version_argument_decoders(145self.environment, program, version,146)147case "client":148for version in node.versions:149emit_version_result_decoders(150self.environment, program, version,151)152153def emit_encoder(self, node: _RpcProgram) -> None:154"""Emit all encoder functions for an RPC program's procedures"""155raw_name = node.name156program = raw_name.lower().removesuffix("_program").removesuffix("_prog")157match self.peer:158case "server":159for version in node.versions:160emit_version_result_encoders(161self.environment, program, version,162)163case "client":164for version in node.versions:165emit_version_argument_encoders(166self.environment, program, version,167)168169170