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