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 to handle XDR unions""" 4 """Generate code to handle XDR unions""" 5 5 6 from jinja2 import Environment 6 from jinja2 import Environment 7 7 8 from generators import SourceGenerator 8 from generators import SourceGenerator 9 from generators import create_jinja2_environme 9 from generators import create_jinja2_environment, get_jinja2_template 10 10 11 from xdr_ast import _XdrBasic, _XdrUnion, _Xdr 11 from xdr_ast import _XdrBasic, _XdrUnion, _XdrVoid 12 from xdr_ast import _XdrDeclaration, _XdrCaseS 12 from xdr_ast import _XdrDeclaration, _XdrCaseSpec, public_apis 13 13 14 14 15 def emit_union_declaration(environment: Enviro 15 def emit_union_declaration(environment: Environment, node: _XdrUnion) -> None: 16 """Emit one declaration pair for an XDR un 16 """Emit one declaration pair for an XDR union type""" 17 if node.name in public_apis: 17 if node.name in public_apis: 18 template = get_jinja2_template(environ 18 template = get_jinja2_template(environment, "declaration", "close") 19 print(template.render(name=node.name)) 19 print(template.render(name=node.name)) 20 20 21 21 22 def emit_union_switch_spec_definition( 22 def emit_union_switch_spec_definition( 23 environment: Environment, node: _XdrDeclar 23 environment: Environment, node: _XdrDeclaration 24 ) -> None: 24 ) -> None: 25 """Emit a definition for an XDR union's di 25 """Emit a definition for an XDR union's discriminant""" 26 assert isinstance(node, _XdrBasic) 26 assert isinstance(node, _XdrBasic) 27 template = get_jinja2_template(environment 27 template = get_jinja2_template(environment, "definition", "switch_spec") 28 print( 28 print( 29 template.render( 29 template.render( 30 name=node.name, 30 name=node.name, 31 type=node.spec.type_name, 31 type=node.spec.type_name, 32 classifier=node.spec.c_classifier, 32 classifier=node.spec.c_classifier, 33 ) 33 ) 34 ) 34 ) 35 35 36 36 37 def emit_union_case_spec_definition( 37 def emit_union_case_spec_definition( 38 environment: Environment, node: _XdrDeclar 38 environment: Environment, node: _XdrDeclaration 39 ) -> None: 39 ) -> None: 40 """Emit a definition for an XDR union's ca 40 """Emit a definition for an XDR union's case arm""" 41 if isinstance(node.arm, _XdrVoid): 41 if isinstance(node.arm, _XdrVoid): 42 return 42 return 43 assert isinstance(node.arm, _XdrBasic) 43 assert isinstance(node.arm, _XdrBasic) 44 template = get_jinja2_template(environment 44 template = get_jinja2_template(environment, "definition", "case_spec") 45 print( 45 print( 46 template.render( 46 template.render( 47 name=node.arm.name, 47 name=node.arm.name, 48 type=node.arm.spec.type_name, 48 type=node.arm.spec.type_name, 49 classifier=node.arm.spec.c_classif 49 classifier=node.arm.spec.c_classifier, 50 ) 50 ) 51 ) 51 ) 52 52 53 53 54 def emit_union_definition(environment: Environ 54 def emit_union_definition(environment: Environment, node: _XdrUnion) -> None: 55 """Emit one XDR union definition""" 55 """Emit one XDR union definition""" 56 template = get_jinja2_template(environment 56 template = get_jinja2_template(environment, "definition", "open") 57 print(template.render(name=node.name)) 57 print(template.render(name=node.name)) 58 58 59 emit_union_switch_spec_definition(environm 59 emit_union_switch_spec_definition(environment, node.discriminant) 60 60 61 for case in node.cases: 61 for case in node.cases: 62 emit_union_case_spec_definition(enviro 62 emit_union_case_spec_definition(environment, case) 63 63 64 if node.default is not None: 64 if node.default is not None: 65 emit_union_case_spec_definition(enviro 65 emit_union_case_spec_definition(environment, node.default) 66 66 67 template = get_jinja2_template(environment 67 template = get_jinja2_template(environment, "definition", "close") 68 print(template.render(name=node.name)) 68 print(template.render(name=node.name)) 69 69 70 70 71 def emit_union_switch_spec_decoder( 71 def emit_union_switch_spec_decoder( 72 environment: Environment, node: _XdrDeclar 72 environment: Environment, node: _XdrDeclaration 73 ) -> None: 73 ) -> None: 74 """Emit a decoder for an XDR union's discr 74 """Emit a decoder for an XDR union's discriminant""" 75 assert isinstance(node, _XdrBasic) 75 assert isinstance(node, _XdrBasic) 76 template = get_jinja2_template(environment 76 template = get_jinja2_template(environment, "decoder", "switch_spec") 77 print(template.render(name=node.name, type 77 print(template.render(name=node.name, type=node.spec.type_name)) 78 78 79 79 80 def emit_union_case_spec_decoder(environment: 80 def emit_union_case_spec_decoder(environment: Environment, node: _XdrCaseSpec) -> None: 81 """Emit decoder functions for an XDR union 81 """Emit decoder functions for an XDR union's case arm""" 82 82 83 if isinstance(node.arm, _XdrVoid): 83 if isinstance(node.arm, _XdrVoid): 84 return 84 return 85 85 86 template = get_jinja2_template(environment 86 template = get_jinja2_template(environment, "decoder", "case_spec") 87 for case in node.values: 87 for case in node.values: 88 print(template.render(case=case)) 88 print(template.render(case=case)) 89 89 90 assert isinstance(node.arm, _XdrBasic) 90 assert isinstance(node.arm, _XdrBasic) 91 template = get_jinja2_template(environment 91 template = get_jinja2_template(environment, "decoder", node.arm.template) 92 print( 92 print( 93 template.render( 93 template.render( 94 name=node.arm.name, 94 name=node.arm.name, 95 type=node.arm.spec.type_name, 95 type=node.arm.spec.type_name, 96 classifier=node.arm.spec.c_classif 96 classifier=node.arm.spec.c_classifier, 97 ) 97 ) 98 ) 98 ) 99 99 100 template = get_jinja2_template(environment 100 template = get_jinja2_template(environment, "decoder", "break") 101 print(template.render()) 101 print(template.render()) 102 102 103 103 104 def emit_union_default_spec_decoder(environmen 104 def emit_union_default_spec_decoder(environment: Environment, node: _XdrUnion) -> None: 105 """Emit a decoder function for an XDR unio 105 """Emit a decoder function for an XDR union's default arm""" 106 default_case = node.default 106 default_case = node.default 107 107 108 # Avoid a gcc warning about a default case 108 # Avoid a gcc warning about a default case with boolean discriminant 109 if default_case is None and node.discrimin 109 if default_case is None and node.discriminant.spec.type_name == "bool": 110 return 110 return 111 111 112 template = get_jinja2_template(environment 112 template = get_jinja2_template(environment, "decoder", "default_spec") 113 print(template.render()) 113 print(template.render()) 114 114 115 if default_case is None or isinstance(defa 115 if default_case is None or isinstance(default_case.arm, _XdrVoid): 116 template = get_jinja2_template(environ 116 template = get_jinja2_template(environment, "decoder", "break") 117 print(template.render()) 117 print(template.render()) 118 return 118 return 119 119 120 assert isinstance(default_case.arm, _XdrBa 120 assert isinstance(default_case.arm, _XdrBasic) 121 template = get_jinja2_template(environment 121 template = get_jinja2_template(environment, "decoder", default_case.arm.template) 122 print( 122 print( 123 template.render( 123 template.render( 124 name=default_case.arm.name, 124 name=default_case.arm.name, 125 type=default_case.arm.spec.type_na 125 type=default_case.arm.spec.type_name, 126 classifier=default_case.arm.spec.c 126 classifier=default_case.arm.spec.c_classifier, 127 ) 127 ) 128 ) 128 ) 129 129 130 130 131 def emit_union_decoder(environment: Environmen 131 def emit_union_decoder(environment: Environment, node: _XdrUnion) -> None: 132 """Emit one XDR union decoder""" 132 """Emit one XDR union decoder""" 133 template = get_jinja2_template(environment 133 template = get_jinja2_template(environment, "decoder", "open") 134 print(template.render(name=node.name)) 134 print(template.render(name=node.name)) 135 135 136 emit_union_switch_spec_decoder(environment 136 emit_union_switch_spec_decoder(environment, node.discriminant) 137 137 138 for case in node.cases: 138 for case in node.cases: 139 emit_union_case_spec_decoder(environme 139 emit_union_case_spec_decoder(environment, case) 140 140 141 emit_union_default_spec_decoder(environmen 141 emit_union_default_spec_decoder(environment, node) 142 142 143 template = get_jinja2_template(environment 143 template = get_jinja2_template(environment, "decoder", "close") 144 print(template.render()) 144 print(template.render()) 145 145 146 146 147 def emit_union_switch_spec_encoder( 147 def emit_union_switch_spec_encoder( 148 environment: Environment, node: _XdrDeclar 148 environment: Environment, node: _XdrDeclaration 149 ) -> None: 149 ) -> None: 150 """Emit an encoder for an XDR union's disc 150 """Emit an encoder for an XDR union's discriminant""" 151 assert isinstance(node, _XdrBasic) 151 assert isinstance(node, _XdrBasic) 152 template = get_jinja2_template(environment 152 template = get_jinja2_template(environment, "encoder", "switch_spec") 153 print(template.render(name=node.name, type 153 print(template.render(name=node.name, type=node.spec.type_name)) 154 154 155 155 156 def emit_union_case_spec_encoder(environment: 156 def emit_union_case_spec_encoder(environment: Environment, node: _XdrCaseSpec) -> None: 157 """Emit encoder functions for an XDR union 157 """Emit encoder functions for an XDR union's case arm""" 158 158 159 if isinstance(node.arm, _XdrVoid): 159 if isinstance(node.arm, _XdrVoid): 160 return 160 return 161 161 162 template = get_jinja2_template(environment 162 template = get_jinja2_template(environment, "encoder", "case_spec") 163 for case in node.values: 163 for case in node.values: 164 print(template.render(case=case)) 164 print(template.render(case=case)) 165 165 166 assert isinstance(node.arm, _XdrBasic) 166 assert isinstance(node.arm, _XdrBasic) 167 template = get_jinja2_template(environment 167 template = get_jinja2_template(environment, "encoder", node.arm.template) 168 print( 168 print( 169 template.render( 169 template.render( 170 name=node.arm.name, 170 name=node.arm.name, 171 type=node.arm.spec.type_name, 171 type=node.arm.spec.type_name, 172 ) 172 ) 173 ) 173 ) 174 174 175 template = get_jinja2_template(environment 175 template = get_jinja2_template(environment, "encoder", "break") 176 print(template.render()) 176 print(template.render()) 177 177 178 178 179 def emit_union_default_spec_encoder(environmen 179 def emit_union_default_spec_encoder(environment: Environment, node: _XdrUnion) -> None: 180 """Emit an encoder function for an XDR uni 180 """Emit an encoder function for an XDR union's default arm""" 181 default_case = node.default 181 default_case = node.default 182 182 183 # Avoid a gcc warning about a default case 183 # Avoid a gcc warning about a default case with boolean discriminant 184 if default_case is None and node.discrimin 184 if default_case is None and node.discriminant.spec.type_name == "bool": 185 return 185 return 186 186 187 template = get_jinja2_template(environment 187 template = get_jinja2_template(environment, "encoder", "default_spec") 188 print(template.render()) 188 print(template.render()) 189 189 190 if default_case is None or isinstance(defa 190 if default_case is None or isinstance(default_case.arm, _XdrVoid): 191 template = get_jinja2_template(environ 191 template = get_jinja2_template(environment, "encoder", "break") 192 print(template.render()) 192 print(template.render()) 193 return 193 return 194 194 195 assert isinstance(default_case.arm, _XdrBa 195 assert isinstance(default_case.arm, _XdrBasic) 196 template = get_jinja2_template(environment 196 template = get_jinja2_template(environment, "encoder", default_case.arm.template) 197 print( 197 print( 198 template.render( 198 template.render( 199 name=default_case.arm.name, 199 name=default_case.arm.name, 200 type=default_case.arm.spec.type_na 200 type=default_case.arm.spec.type_name, 201 ) 201 ) 202 ) 202 ) 203 203 204 204 205 def emit_union_encoder(environment, node: _Xdr 205 def emit_union_encoder(environment, node: _XdrUnion) -> None: 206 """Emit one XDR union encoder""" 206 """Emit one XDR union encoder""" 207 template = get_jinja2_template(environment 207 template = get_jinja2_template(environment, "encoder", "open") 208 print(template.render(name=node.name)) 208 print(template.render(name=node.name)) 209 209 210 emit_union_switch_spec_encoder(environment 210 emit_union_switch_spec_encoder(environment, node.discriminant) 211 211 212 for case in node.cases: 212 for case in node.cases: 213 emit_union_case_spec_encoder(environme 213 emit_union_case_spec_encoder(environment, case) 214 214 215 emit_union_default_spec_encoder(environmen 215 emit_union_default_spec_encoder(environment, node) 216 216 217 template = get_jinja2_template(environment 217 template = get_jinja2_template(environment, "encoder", "close") 218 print(template.render()) 218 print(template.render()) 219 219 220 220 221 class XdrUnionGenerator(SourceGenerator): 221 class XdrUnionGenerator(SourceGenerator): 222 """Generate source code for XDR unions""" 222 """Generate source code for XDR unions""" 223 223 224 def __init__(self, language: str, peer: st 224 def __init__(self, language: str, peer: str): 225 """Initialize an instance of this clas 225 """Initialize an instance of this class""" 226 self.environment = create_jinja2_envir 226 self.environment = create_jinja2_environment(language, "union") 227 self.peer = peer 227 self.peer = peer 228 228 229 def emit_declaration(self, node: _XdrUnion 229 def emit_declaration(self, node: _XdrUnion) -> None: 230 """Emit one declaration pair for an XD 230 """Emit one declaration pair for an XDR union""" 231 emit_union_declaration(self.environmen 231 emit_union_declaration(self.environment, node) 232 232 233 def emit_definition(self, node: _XdrUnion) 233 def emit_definition(self, node: _XdrUnion) -> None: 234 """Emit one definition for an XDR unio 234 """Emit one definition for an XDR union""" 235 emit_union_definition(self.environment 235 emit_union_definition(self.environment, node) 236 236 237 def emit_decoder(self, node: _XdrUnion) -> 237 def emit_decoder(self, node: _XdrUnion) -> None: 238 """Emit one decoder function for an XD 238 """Emit one decoder function for an XDR union""" 239 emit_union_decoder(self.environment, n 239 emit_union_decoder(self.environment, node) 240 240 241 def emit_encoder(self, node: _XdrUnion) -> 241 def emit_encoder(self, node: _XdrUnion) -> None: 242 """Emit one encoder function for an XD 242 """Emit one encoder function for an XDR union""" 243 emit_union_encoder(self.environment, n 243 emit_union_encoder(self.environment, node)
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.