1*90277196SAndroid Build Coastguard Worker#!/usr/bin/env python3 -i 2*90277196SAndroid Build Coastguard Worker# 3*90277196SAndroid Build Coastguard Worker# Copyright 2013-2024 The Khronos Group Inc. 4*90277196SAndroid Build Coastguard Worker# 5*90277196SAndroid Build Coastguard Worker# SPDX-License-Identifier: Apache-2.0 6*90277196SAndroid Build Coastguard Worker 7*90277196SAndroid Build Coastguard Worker# Base class for working-group-specific style conventions, 8*90277196SAndroid Build Coastguard Worker# used in generation. 9*90277196SAndroid Build Coastguard Worker 10*90277196SAndroid Build Coastguard Workerfrom enum import Enum 11*90277196SAndroid Build Coastguard Workerimport abc 12*90277196SAndroid Build Coastguard Workerimport re 13*90277196SAndroid Build Coastguard Worker 14*90277196SAndroid Build Coastguard Worker# Type categories that respond "False" to isStructAlwaysValid 15*90277196SAndroid Build Coastguard Worker# basetype is home to typedefs like ..Bool32 16*90277196SAndroid Build Coastguard WorkerCATEGORIES_REQUIRING_VALIDATION = set(('handle', 17*90277196SAndroid Build Coastguard Worker 'enum', 18*90277196SAndroid Build Coastguard Worker 'bitmask', 19*90277196SAndroid Build Coastguard Worker 'basetype', 20*90277196SAndroid Build Coastguard Worker None)) 21*90277196SAndroid Build Coastguard Worker 22*90277196SAndroid Build Coastguard Worker# These are basic C types pulled in via openxr_platform_defines.h 23*90277196SAndroid Build Coastguard WorkerTYPES_KNOWN_ALWAYS_VALID = set(('char', 24*90277196SAndroid Build Coastguard Worker 'float', 25*90277196SAndroid Build Coastguard Worker 'int8_t', 'uint8_t', 26*90277196SAndroid Build Coastguard Worker 'int16_t', 'uint16_t', 27*90277196SAndroid Build Coastguard Worker 'int32_t', 'uint32_t', 28*90277196SAndroid Build Coastguard Worker 'int64_t', 'uint64_t', 29*90277196SAndroid Build Coastguard Worker 'size_t', 30*90277196SAndroid Build Coastguard Worker 'intptr_t', 'uintptr_t', 31*90277196SAndroid Build Coastguard Worker 'int', 32*90277196SAndroid Build Coastguard Worker )) 33*90277196SAndroid Build Coastguard Worker 34*90277196SAndroid Build Coastguard Worker# Split an extension name into vendor ID and name portions 35*90277196SAndroid Build Coastguard WorkerEXT_NAME_DECOMPOSE_RE = re.compile(r'(?P<prefix>[A-Za-z]+)_(?P<vendor>[A-Za-z]+)_(?P<name>[\w_]+)') 36*90277196SAndroid Build Coastguard Worker 37*90277196SAndroid Build Coastguard Worker# Match an API version name. 38*90277196SAndroid Build Coastguard Worker# Match object includes API prefix, major, and minor version numbers. 39*90277196SAndroid Build Coastguard Worker# This could be refined further for specific APIs. 40*90277196SAndroid Build Coastguard WorkerAPI_VERSION_NAME_RE = re.compile(r'(?P<apivariant>[A-Za-z]+)_VERSION_(?P<major>[0-9]+)_(?P<minor>[0-9]+)') 41*90277196SAndroid Build Coastguard Worker 42*90277196SAndroid Build Coastguard Workerclass ProseListFormats(Enum): 43*90277196SAndroid Build Coastguard Worker """A connective, possibly with a quantifier.""" 44*90277196SAndroid Build Coastguard Worker AND = 0 45*90277196SAndroid Build Coastguard Worker EACH_AND = 1 46*90277196SAndroid Build Coastguard Worker OR = 2 47*90277196SAndroid Build Coastguard Worker ANY_OR = 3 48*90277196SAndroid Build Coastguard Worker 49*90277196SAndroid Build Coastguard Worker @classmethod 50*90277196SAndroid Build Coastguard Worker def from_string(cls, s): 51*90277196SAndroid Build Coastguard Worker if s == 'or': 52*90277196SAndroid Build Coastguard Worker return cls.OR 53*90277196SAndroid Build Coastguard Worker if s == 'and': 54*90277196SAndroid Build Coastguard Worker return cls.AND 55*90277196SAndroid Build Coastguard Worker raise RuntimeError("Unrecognized string connective: " + s) 56*90277196SAndroid Build Coastguard Worker 57*90277196SAndroid Build Coastguard Worker @property 58*90277196SAndroid Build Coastguard Worker def connective(self): 59*90277196SAndroid Build Coastguard Worker if self in (ProseListFormats.OR, ProseListFormats.ANY_OR): 60*90277196SAndroid Build Coastguard Worker return 'or' 61*90277196SAndroid Build Coastguard Worker return 'and' 62*90277196SAndroid Build Coastguard Worker 63*90277196SAndroid Build Coastguard Worker def quantifier(self, n): 64*90277196SAndroid Build Coastguard Worker """Return the desired quantifier for a list of a given length.""" 65*90277196SAndroid Build Coastguard Worker if self == ProseListFormats.ANY_OR: 66*90277196SAndroid Build Coastguard Worker if n > 1: 67*90277196SAndroid Build Coastguard Worker return 'any of ' 68*90277196SAndroid Build Coastguard Worker elif self == ProseListFormats.EACH_AND: 69*90277196SAndroid Build Coastguard Worker if n > 2: 70*90277196SAndroid Build Coastguard Worker return 'each of ' 71*90277196SAndroid Build Coastguard Worker if n == 2: 72*90277196SAndroid Build Coastguard Worker return 'both of ' 73*90277196SAndroid Build Coastguard Worker return '' 74*90277196SAndroid Build Coastguard Worker 75*90277196SAndroid Build Coastguard Worker 76*90277196SAndroid Build Coastguard Workerclass ConventionsBase(abc.ABC): 77*90277196SAndroid Build Coastguard Worker """WG-specific conventions.""" 78*90277196SAndroid Build Coastguard Worker 79*90277196SAndroid Build Coastguard Worker def __init__(self): 80*90277196SAndroid Build Coastguard Worker self._command_prefix = None 81*90277196SAndroid Build Coastguard Worker self._type_prefix = None 82*90277196SAndroid Build Coastguard Worker 83*90277196SAndroid Build Coastguard Worker def formatVersionOrExtension(self, name): 84*90277196SAndroid Build Coastguard Worker """Mark up an API version or extension name as a link in the spec.""" 85*90277196SAndroid Build Coastguard Worker 86*90277196SAndroid Build Coastguard Worker # Is this a version name? 87*90277196SAndroid Build Coastguard Worker match = API_VERSION_NAME_RE.match(name) 88*90277196SAndroid Build Coastguard Worker if match is not None: 89*90277196SAndroid Build Coastguard Worker return self.formatVersion(name, 90*90277196SAndroid Build Coastguard Worker match.group('apivariant'), 91*90277196SAndroid Build Coastguard Worker match.group('major'), 92*90277196SAndroid Build Coastguard Worker match.group('minor')) 93*90277196SAndroid Build Coastguard Worker else: 94*90277196SAndroid Build Coastguard Worker # If not, assumed to be an extension name. Might be worth checking. 95*90277196SAndroid Build Coastguard Worker return self.formatExtension(name) 96*90277196SAndroid Build Coastguard Worker 97*90277196SAndroid Build Coastguard Worker def formatVersion(self, name, apivariant, major, minor): 98*90277196SAndroid Build Coastguard Worker """Mark up an API version name as a link in the spec.""" 99*90277196SAndroid Build Coastguard Worker return '`<<{}>>`'.format(name) 100*90277196SAndroid Build Coastguard Worker 101*90277196SAndroid Build Coastguard Worker def formatExtension(self, name): 102*90277196SAndroid Build Coastguard Worker """Mark up an extension name as a link in the spec.""" 103*90277196SAndroid Build Coastguard Worker return '`<<{}>>`'.format(name) 104*90277196SAndroid Build Coastguard Worker 105*90277196SAndroid Build Coastguard Worker def formatSPIRVlink(self, name): 106*90277196SAndroid Build Coastguard Worker """Mark up a SPIR-V extension name as an external link in the spec. 107*90277196SAndroid Build Coastguard Worker Since these are external links, the formatting probably will be 108*90277196SAndroid Build Coastguard Worker the same for all APIs creating such links, so long as they use 109*90277196SAndroid Build Coastguard Worker the asciidoctor {spirv} attribute for the base path to the SPIR-V 110*90277196SAndroid Build Coastguard Worker extensions.""" 111*90277196SAndroid Build Coastguard Worker 112*90277196SAndroid Build Coastguard Worker (vendor, _) = self.extension_name_split(name) 113*90277196SAndroid Build Coastguard Worker 114*90277196SAndroid Build Coastguard Worker return f'{{spirv}}/{vendor}/{name}.html[{name}]' 115*90277196SAndroid Build Coastguard Worker 116*90277196SAndroid Build Coastguard Worker @property 117*90277196SAndroid Build Coastguard Worker @abc.abstractmethod 118*90277196SAndroid Build Coastguard Worker def null(self): 119*90277196SAndroid Build Coastguard Worker """Preferred spelling of NULL.""" 120*90277196SAndroid Build Coastguard Worker raise NotImplementedError 121*90277196SAndroid Build Coastguard Worker 122*90277196SAndroid Build Coastguard Worker def makeProseList(self, elements, fmt=ProseListFormats.AND, with_verb=False, *args, **kwargs): 123*90277196SAndroid Build Coastguard Worker """Make a (comma-separated) list for use in prose. 124*90277196SAndroid Build Coastguard Worker 125*90277196SAndroid Build Coastguard Worker Adds a connective (by default, 'and') 126*90277196SAndroid Build Coastguard Worker before the last element if there are more than 1. 127*90277196SAndroid Build Coastguard Worker 128*90277196SAndroid Build Coastguard Worker Adds the right one of "is" or "are" to the end if with_verb is true. 129*90277196SAndroid Build Coastguard Worker 130*90277196SAndroid Build Coastguard Worker Optionally adds a quantifier (like 'any') before a list of 2 or more, 131*90277196SAndroid Build Coastguard Worker if specified by fmt. 132*90277196SAndroid Build Coastguard Worker 133*90277196SAndroid Build Coastguard Worker Override with a different method or different call to 134*90277196SAndroid Build Coastguard Worker _implMakeProseList if you want to add a comma for two elements, 135*90277196SAndroid Build Coastguard Worker or not use a serial comma. 136*90277196SAndroid Build Coastguard Worker """ 137*90277196SAndroid Build Coastguard Worker return self._implMakeProseList(elements, fmt, with_verb, *args, **kwargs) 138*90277196SAndroid Build Coastguard Worker 139*90277196SAndroid Build Coastguard Worker @property 140*90277196SAndroid Build Coastguard Worker def struct_macro(self): 141*90277196SAndroid Build Coastguard Worker """Get the appropriate format macro for a structure. 142*90277196SAndroid Build Coastguard Worker 143*90277196SAndroid Build Coastguard Worker May override. 144*90277196SAndroid Build Coastguard Worker """ 145*90277196SAndroid Build Coastguard Worker return 'slink:' 146*90277196SAndroid Build Coastguard Worker 147*90277196SAndroid Build Coastguard Worker @property 148*90277196SAndroid Build Coastguard Worker def external_macro(self): 149*90277196SAndroid Build Coastguard Worker """Get the appropriate format macro for an external type like uint32_t. 150*90277196SAndroid Build Coastguard Worker 151*90277196SAndroid Build Coastguard Worker May override. 152*90277196SAndroid Build Coastguard Worker """ 153*90277196SAndroid Build Coastguard Worker return 'code:' 154*90277196SAndroid Build Coastguard Worker 155*90277196SAndroid Build Coastguard Worker @property 156*90277196SAndroid Build Coastguard Worker def allows_x_number_suffix(self): 157*90277196SAndroid Build Coastguard Worker """Whether vendor tags can be suffixed with X and a number to mark experimental extensions.""" 158*90277196SAndroid Build Coastguard Worker return False 159*90277196SAndroid Build Coastguard Worker 160*90277196SAndroid Build Coastguard Worker @property 161*90277196SAndroid Build Coastguard Worker @abc.abstractmethod 162*90277196SAndroid Build Coastguard Worker def structtype_member_name(self): 163*90277196SAndroid Build Coastguard Worker """Return name of the structure type member. 164*90277196SAndroid Build Coastguard Worker 165*90277196SAndroid Build Coastguard Worker Must implement. 166*90277196SAndroid Build Coastguard Worker """ 167*90277196SAndroid Build Coastguard Worker raise NotImplementedError() 168*90277196SAndroid Build Coastguard Worker 169*90277196SAndroid Build Coastguard Worker @property 170*90277196SAndroid Build Coastguard Worker @abc.abstractmethod 171*90277196SAndroid Build Coastguard Worker def nextpointer_member_name(self): 172*90277196SAndroid Build Coastguard Worker """Return name of the structure pointer chain member. 173*90277196SAndroid Build Coastguard Worker 174*90277196SAndroid Build Coastguard Worker Must implement. 175*90277196SAndroid Build Coastguard Worker """ 176*90277196SAndroid Build Coastguard Worker raise NotImplementedError() 177*90277196SAndroid Build Coastguard Worker 178*90277196SAndroid Build Coastguard Worker @property 179*90277196SAndroid Build Coastguard Worker @abc.abstractmethod 180*90277196SAndroid Build Coastguard Worker def xml_api_name(self): 181*90277196SAndroid Build Coastguard Worker """Return the name used in the default API XML registry for the default API""" 182*90277196SAndroid Build Coastguard Worker raise NotImplementedError() 183*90277196SAndroid Build Coastguard Worker 184*90277196SAndroid Build Coastguard Worker @abc.abstractmethod 185*90277196SAndroid Build Coastguard Worker def generate_structure_type_from_name(self, structname): 186*90277196SAndroid Build Coastguard Worker """Generate a structure type name, like XR_TYPE_CREATE_INSTANCE_INFO. 187*90277196SAndroid Build Coastguard Worker 188*90277196SAndroid Build Coastguard Worker Must implement. 189*90277196SAndroid Build Coastguard Worker """ 190*90277196SAndroid Build Coastguard Worker raise NotImplementedError() 191*90277196SAndroid Build Coastguard Worker 192*90277196SAndroid Build Coastguard Worker def makeStructName(self, name): 193*90277196SAndroid Build Coastguard Worker """Prepend the appropriate format macro for a structure to a structure type name. 194*90277196SAndroid Build Coastguard Worker 195*90277196SAndroid Build Coastguard Worker Uses struct_macro, so just override that if you want to change behavior. 196*90277196SAndroid Build Coastguard Worker """ 197*90277196SAndroid Build Coastguard Worker return self.struct_macro + name 198*90277196SAndroid Build Coastguard Worker 199*90277196SAndroid Build Coastguard Worker def makeExternalTypeName(self, name): 200*90277196SAndroid Build Coastguard Worker """Prepend the appropriate format macro for an external type like uint32_t to a type name. 201*90277196SAndroid Build Coastguard Worker 202*90277196SAndroid Build Coastguard Worker Uses external_macro, so just override that if you want to change behavior. 203*90277196SAndroid Build Coastguard Worker """ 204*90277196SAndroid Build Coastguard Worker return self.external_macro + name 205*90277196SAndroid Build Coastguard Worker 206*90277196SAndroid Build Coastguard Worker def _implMakeProseList(self, elements, fmt, with_verb, comma_for_two_elts=False, serial_comma=True): 207*90277196SAndroid Build Coastguard Worker """Internal-use implementation to make a (comma-separated) list for use in prose. 208*90277196SAndroid Build Coastguard Worker 209*90277196SAndroid Build Coastguard Worker Adds a connective (by default, 'and') 210*90277196SAndroid Build Coastguard Worker before the last element if there are more than 1, 211*90277196SAndroid Build Coastguard Worker and only includes commas if there are more than 2 212*90277196SAndroid Build Coastguard Worker (if comma_for_two_elts is False). 213*90277196SAndroid Build Coastguard Worker 214*90277196SAndroid Build Coastguard Worker Adds the right one of "is" or "are" to the end if with_verb is true. 215*90277196SAndroid Build Coastguard Worker 216*90277196SAndroid Build Coastguard Worker Optionally adds a quantifier (like 'any') before a list of 2 or more, 217*90277196SAndroid Build Coastguard Worker if specified by fmt. 218*90277196SAndroid Build Coastguard Worker 219*90277196SAndroid Build Coastguard Worker Do not edit these defaults, override self.makeProseList(). 220*90277196SAndroid Build Coastguard Worker """ 221*90277196SAndroid Build Coastguard Worker assert serial_comma # did not implement what we did not need 222*90277196SAndroid Build Coastguard Worker if isinstance(fmt, str): 223*90277196SAndroid Build Coastguard Worker fmt = ProseListFormats.from_string(fmt) 224*90277196SAndroid Build Coastguard Worker 225*90277196SAndroid Build Coastguard Worker my_elts = list(elements) 226*90277196SAndroid Build Coastguard Worker if len(my_elts) > 1: 227*90277196SAndroid Build Coastguard Worker my_elts[-1] = '{} {}'.format(fmt.connective, my_elts[-1]) 228*90277196SAndroid Build Coastguard Worker 229*90277196SAndroid Build Coastguard Worker if not comma_for_two_elts and len(my_elts) <= 2: 230*90277196SAndroid Build Coastguard Worker prose = ' '.join(my_elts) 231*90277196SAndroid Build Coastguard Worker else: 232*90277196SAndroid Build Coastguard Worker prose = ', '.join(my_elts) 233*90277196SAndroid Build Coastguard Worker 234*90277196SAndroid Build Coastguard Worker quantifier = fmt.quantifier(len(my_elts)) 235*90277196SAndroid Build Coastguard Worker 236*90277196SAndroid Build Coastguard Worker parts = [quantifier, prose] 237*90277196SAndroid Build Coastguard Worker 238*90277196SAndroid Build Coastguard Worker if with_verb: 239*90277196SAndroid Build Coastguard Worker if len(my_elts) > 1: 240*90277196SAndroid Build Coastguard Worker parts.append(' are') 241*90277196SAndroid Build Coastguard Worker else: 242*90277196SAndroid Build Coastguard Worker parts.append(' is') 243*90277196SAndroid Build Coastguard Worker return ''.join(parts) 244*90277196SAndroid Build Coastguard Worker 245*90277196SAndroid Build Coastguard Worker @property 246*90277196SAndroid Build Coastguard Worker @abc.abstractmethod 247*90277196SAndroid Build Coastguard Worker def file_suffix(self): 248*90277196SAndroid Build Coastguard Worker """Return suffix of generated Asciidoctor files""" 249*90277196SAndroid Build Coastguard Worker raise NotImplementedError 250*90277196SAndroid Build Coastguard Worker 251*90277196SAndroid Build Coastguard Worker @abc.abstractmethod 252*90277196SAndroid Build Coastguard Worker def api_name(self, spectype=None): 253*90277196SAndroid Build Coastguard Worker """Return API or specification name for citations in ref pages. 254*90277196SAndroid Build Coastguard Worker 255*90277196SAndroid Build Coastguard Worker spectype is the spec this refpage is for. 256*90277196SAndroid Build Coastguard Worker 'api' (the default value) is the main API Specification. 257*90277196SAndroid Build Coastguard Worker If an unrecognized spectype is given, returns None. 258*90277196SAndroid Build Coastguard Worker 259*90277196SAndroid Build Coastguard Worker Must implement.""" 260*90277196SAndroid Build Coastguard Worker raise NotImplementedError 261*90277196SAndroid Build Coastguard Worker 262*90277196SAndroid Build Coastguard Worker def should_insert_may_alias_macro(self, genOpts): 263*90277196SAndroid Build Coastguard Worker """Return true if we should insert a "may alias" macro in this file. 264*90277196SAndroid Build Coastguard Worker 265*90277196SAndroid Build Coastguard Worker Only used by OpenXR right now.""" 266*90277196SAndroid Build Coastguard Worker return False 267*90277196SAndroid Build Coastguard Worker 268*90277196SAndroid Build Coastguard Worker @property 269*90277196SAndroid Build Coastguard Worker def command_prefix(self): 270*90277196SAndroid Build Coastguard Worker """Return the expected prefix of commands/functions. 271*90277196SAndroid Build Coastguard Worker 272*90277196SAndroid Build Coastguard Worker Implemented in terms of api_prefix.""" 273*90277196SAndroid Build Coastguard Worker if not self._command_prefix: 274*90277196SAndroid Build Coastguard Worker self._command_prefix = self.api_prefix[:].replace('_', '').lower() 275*90277196SAndroid Build Coastguard Worker return self._command_prefix 276*90277196SAndroid Build Coastguard Worker 277*90277196SAndroid Build Coastguard Worker @property 278*90277196SAndroid Build Coastguard Worker def type_prefix(self): 279*90277196SAndroid Build Coastguard Worker """Return the expected prefix of type names. 280*90277196SAndroid Build Coastguard Worker 281*90277196SAndroid Build Coastguard Worker Implemented in terms of command_prefix (and in turn, api_prefix).""" 282*90277196SAndroid Build Coastguard Worker if not self._type_prefix: 283*90277196SAndroid Build Coastguard Worker self._type_prefix = ''.join( 284*90277196SAndroid Build Coastguard Worker (self.command_prefix[0:1].upper(), self.command_prefix[1:])) 285*90277196SAndroid Build Coastguard Worker return self._type_prefix 286*90277196SAndroid Build Coastguard Worker 287*90277196SAndroid Build Coastguard Worker @property 288*90277196SAndroid Build Coastguard Worker @abc.abstractmethod 289*90277196SAndroid Build Coastguard Worker def api_prefix(self): 290*90277196SAndroid Build Coastguard Worker """Return API token prefix. 291*90277196SAndroid Build Coastguard Worker 292*90277196SAndroid Build Coastguard Worker Typically two uppercase letters followed by an underscore. 293*90277196SAndroid Build Coastguard Worker 294*90277196SAndroid Build Coastguard Worker Must implement.""" 295*90277196SAndroid Build Coastguard Worker raise NotImplementedError 296*90277196SAndroid Build Coastguard Worker 297*90277196SAndroid Build Coastguard Worker @property 298*90277196SAndroid Build Coastguard Worker def extension_name_prefix(self): 299*90277196SAndroid Build Coastguard Worker """Return extension name prefix. 300*90277196SAndroid Build Coastguard Worker 301*90277196SAndroid Build Coastguard Worker Typically two uppercase letters followed by an underscore. 302*90277196SAndroid Build Coastguard Worker 303*90277196SAndroid Build Coastguard Worker Assumed to be the same as api_prefix, but some APIs use different 304*90277196SAndroid Build Coastguard Worker case conventions.""" 305*90277196SAndroid Build Coastguard Worker 306*90277196SAndroid Build Coastguard Worker return self.api_prefix 307*90277196SAndroid Build Coastguard Worker 308*90277196SAndroid Build Coastguard Worker def extension_short_description(self, elem): 309*90277196SAndroid Build Coastguard Worker """Return a short description of an extension for use in refpages. 310*90277196SAndroid Build Coastguard Worker 311*90277196SAndroid Build Coastguard Worker elem is an ElementTree for the <extension> tag in the XML. 312*90277196SAndroid Build Coastguard Worker The default behavior is to use the 'type' field of this tag, but not 313*90277196SAndroid Build Coastguard Worker all APIs support this field.""" 314*90277196SAndroid Build Coastguard Worker 315*90277196SAndroid Build Coastguard Worker ext_type = elem.get('type') 316*90277196SAndroid Build Coastguard Worker 317*90277196SAndroid Build Coastguard Worker if ext_type is not None: 318*90277196SAndroid Build Coastguard Worker return f'{ext_type} extension' 319*90277196SAndroid Build Coastguard Worker else: 320*90277196SAndroid Build Coastguard Worker return '' 321*90277196SAndroid Build Coastguard Worker 322*90277196SAndroid Build Coastguard Worker @property 323*90277196SAndroid Build Coastguard Worker def write_contacts(self): 324*90277196SAndroid Build Coastguard Worker """Return whether contact list should be written to extension appendices""" 325*90277196SAndroid Build Coastguard Worker return False 326*90277196SAndroid Build Coastguard Worker 327*90277196SAndroid Build Coastguard Worker @property 328*90277196SAndroid Build Coastguard Worker def write_extension_type(self): 329*90277196SAndroid Build Coastguard Worker """Return whether extension type should be written to extension appendices""" 330*90277196SAndroid Build Coastguard Worker return True 331*90277196SAndroid Build Coastguard Worker 332*90277196SAndroid Build Coastguard Worker @property 333*90277196SAndroid Build Coastguard Worker def write_extension_number(self): 334*90277196SAndroid Build Coastguard Worker """Return whether extension number should be written to extension appendices""" 335*90277196SAndroid Build Coastguard Worker return True 336*90277196SAndroid Build Coastguard Worker 337*90277196SAndroid Build Coastguard Worker @property 338*90277196SAndroid Build Coastguard Worker def write_extension_revision(self): 339*90277196SAndroid Build Coastguard Worker """Return whether extension revision number should be written to extension appendices""" 340*90277196SAndroid Build Coastguard Worker return True 341*90277196SAndroid Build Coastguard Worker 342*90277196SAndroid Build Coastguard Worker @property 343*90277196SAndroid Build Coastguard Worker def write_refpage_include(self): 344*90277196SAndroid Build Coastguard Worker """Return whether refpage include should be written to extension appendices""" 345*90277196SAndroid Build Coastguard Worker return True 346*90277196SAndroid Build Coastguard Worker 347*90277196SAndroid Build Coastguard Worker @property 348*90277196SAndroid Build Coastguard Worker def api_version_prefix(self): 349*90277196SAndroid Build Coastguard Worker """Return API core version token prefix. 350*90277196SAndroid Build Coastguard Worker 351*90277196SAndroid Build Coastguard Worker Implemented in terms of api_prefix. 352*90277196SAndroid Build Coastguard Worker 353*90277196SAndroid Build Coastguard Worker May override.""" 354*90277196SAndroid Build Coastguard Worker return self.api_prefix + 'VERSION_' 355*90277196SAndroid Build Coastguard Worker 356*90277196SAndroid Build Coastguard Worker @property 357*90277196SAndroid Build Coastguard Worker def KHR_prefix(self): 358*90277196SAndroid Build Coastguard Worker """Return extension name prefix for KHR extensions. 359*90277196SAndroid Build Coastguard Worker 360*90277196SAndroid Build Coastguard Worker Implemented in terms of api_prefix. 361*90277196SAndroid Build Coastguard Worker 362*90277196SAndroid Build Coastguard Worker May override.""" 363*90277196SAndroid Build Coastguard Worker return self.api_prefix + 'KHR_' 364*90277196SAndroid Build Coastguard Worker 365*90277196SAndroid Build Coastguard Worker @property 366*90277196SAndroid Build Coastguard Worker def EXT_prefix(self): 367*90277196SAndroid Build Coastguard Worker """Return extension name prefix for EXT extensions. 368*90277196SAndroid Build Coastguard Worker 369*90277196SAndroid Build Coastguard Worker Implemented in terms of api_prefix. 370*90277196SAndroid Build Coastguard Worker 371*90277196SAndroid Build Coastguard Worker May override.""" 372*90277196SAndroid Build Coastguard Worker return self.api_prefix + 'EXT_' 373*90277196SAndroid Build Coastguard Worker 374*90277196SAndroid Build Coastguard Worker def writeFeature(self, featureName, featureExtraProtect, filename): 375*90277196SAndroid Build Coastguard Worker """Return True if OutputGenerator.endFeature should write this feature. 376*90277196SAndroid Build Coastguard Worker 377*90277196SAndroid Build Coastguard Worker Defaults to always True. 378*90277196SAndroid Build Coastguard Worker Used in COutputGenerator. 379*90277196SAndroid Build Coastguard Worker 380*90277196SAndroid Build Coastguard Worker May override.""" 381*90277196SAndroid Build Coastguard Worker return True 382*90277196SAndroid Build Coastguard Worker 383*90277196SAndroid Build Coastguard Worker def requires_error_validation(self, return_type): 384*90277196SAndroid Build Coastguard Worker """Return True if the return_type element is an API result code 385*90277196SAndroid Build Coastguard Worker requiring error validation. 386*90277196SAndroid Build Coastguard Worker 387*90277196SAndroid Build Coastguard Worker Defaults to always False. 388*90277196SAndroid Build Coastguard Worker 389*90277196SAndroid Build Coastguard Worker May override.""" 390*90277196SAndroid Build Coastguard Worker return False 391*90277196SAndroid Build Coastguard Worker 392*90277196SAndroid Build Coastguard Worker @property 393*90277196SAndroid Build Coastguard Worker def required_errors(self): 394*90277196SAndroid Build Coastguard Worker """Return a list of required error codes for validation. 395*90277196SAndroid Build Coastguard Worker 396*90277196SAndroid Build Coastguard Worker Defaults to an empty list. 397*90277196SAndroid Build Coastguard Worker 398*90277196SAndroid Build Coastguard Worker May override.""" 399*90277196SAndroid Build Coastguard Worker return [] 400*90277196SAndroid Build Coastguard Worker 401*90277196SAndroid Build Coastguard Worker def is_voidpointer_alias(self, tag, text, tail): 402*90277196SAndroid Build Coastguard Worker """Return True if the declaration components (tag,text,tail) of an 403*90277196SAndroid Build Coastguard Worker element represents a void * type. 404*90277196SAndroid Build Coastguard Worker 405*90277196SAndroid Build Coastguard Worker Defaults to a reasonable implementation. 406*90277196SAndroid Build Coastguard Worker 407*90277196SAndroid Build Coastguard Worker May override.""" 408*90277196SAndroid Build Coastguard Worker return tag == 'type' and text == 'void' and tail.startswith('*') 409*90277196SAndroid Build Coastguard Worker 410*90277196SAndroid Build Coastguard Worker def make_voidpointer_alias(self, tail): 411*90277196SAndroid Build Coastguard Worker """Reformat a void * declaration to include the API alias macro. 412*90277196SAndroid Build Coastguard Worker 413*90277196SAndroid Build Coastguard Worker Defaults to a no-op. 414*90277196SAndroid Build Coastguard Worker 415*90277196SAndroid Build Coastguard Worker Must override if you actually want to use this feature in your project.""" 416*90277196SAndroid Build Coastguard Worker return tail 417*90277196SAndroid Build Coastguard Worker 418*90277196SAndroid Build Coastguard Worker def category_requires_validation(self, category): 419*90277196SAndroid Build Coastguard Worker """Return True if the given type 'category' always requires validation. 420*90277196SAndroid Build Coastguard Worker 421*90277196SAndroid Build Coastguard Worker Defaults to a reasonable implementation. 422*90277196SAndroid Build Coastguard Worker 423*90277196SAndroid Build Coastguard Worker May override.""" 424*90277196SAndroid Build Coastguard Worker return category in CATEGORIES_REQUIRING_VALIDATION 425*90277196SAndroid Build Coastguard Worker 426*90277196SAndroid Build Coastguard Worker def type_always_valid(self, typename): 427*90277196SAndroid Build Coastguard Worker """Return True if the given type name is always valid (never requires validation). 428*90277196SAndroid Build Coastguard Worker 429*90277196SAndroid Build Coastguard Worker This is for things like integers. 430*90277196SAndroid Build Coastguard Worker 431*90277196SAndroid Build Coastguard Worker Defaults to a reasonable implementation. 432*90277196SAndroid Build Coastguard Worker 433*90277196SAndroid Build Coastguard Worker May override.""" 434*90277196SAndroid Build Coastguard Worker return typename in TYPES_KNOWN_ALWAYS_VALID 435*90277196SAndroid Build Coastguard Worker 436*90277196SAndroid Build Coastguard Worker @property 437*90277196SAndroid Build Coastguard Worker def should_skip_checking_codes(self): 438*90277196SAndroid Build Coastguard Worker """Return True if more than the basic validation of return codes should 439*90277196SAndroid Build Coastguard Worker be skipped for a command.""" 440*90277196SAndroid Build Coastguard Worker 441*90277196SAndroid Build Coastguard Worker return False 442*90277196SAndroid Build Coastguard Worker 443*90277196SAndroid Build Coastguard Worker @property 444*90277196SAndroid Build Coastguard Worker def generate_index_terms(self): 445*90277196SAndroid Build Coastguard Worker """Return True if asiidoctor index terms should be generated as part 446*90277196SAndroid Build Coastguard Worker of an API interface from the docgenerator.""" 447*90277196SAndroid Build Coastguard Worker 448*90277196SAndroid Build Coastguard Worker return False 449*90277196SAndroid Build Coastguard Worker 450*90277196SAndroid Build Coastguard Worker @property 451*90277196SAndroid Build Coastguard Worker def generate_enum_table(self): 452*90277196SAndroid Build Coastguard Worker """Return True if asciidoctor tables describing enumerants in a 453*90277196SAndroid Build Coastguard Worker group should be generated as part of group generation.""" 454*90277196SAndroid Build Coastguard Worker return False 455*90277196SAndroid Build Coastguard Worker 456*90277196SAndroid Build Coastguard Worker @property 457*90277196SAndroid Build Coastguard Worker def generate_max_enum_in_docs(self): 458*90277196SAndroid Build Coastguard Worker """Return True if MAX_ENUM tokens should be generated in 459*90277196SAndroid Build Coastguard Worker documentation includes.""" 460*90277196SAndroid Build Coastguard Worker return False 461*90277196SAndroid Build Coastguard Worker 462*90277196SAndroid Build Coastguard Worker def extension_name_split(self, name): 463*90277196SAndroid Build Coastguard Worker """Split an extension name, returning (vendor, rest of name). 464*90277196SAndroid Build Coastguard Worker The API prefix of the name is ignored.""" 465*90277196SAndroid Build Coastguard Worker 466*90277196SAndroid Build Coastguard Worker match = EXT_NAME_DECOMPOSE_RE.match(name) 467*90277196SAndroid Build Coastguard Worker vendor = match.group('vendor') 468*90277196SAndroid Build Coastguard Worker bare_name = match.group('name') 469*90277196SAndroid Build Coastguard Worker 470*90277196SAndroid Build Coastguard Worker return (vendor, bare_name) 471*90277196SAndroid Build Coastguard Worker 472*90277196SAndroid Build Coastguard Worker @abc.abstractmethod 473*90277196SAndroid Build Coastguard Worker def extension_file_path(self, name): 474*90277196SAndroid Build Coastguard Worker """Return file path to an extension appendix relative to a directory 475*90277196SAndroid Build Coastguard Worker containing all such appendices. 476*90277196SAndroid Build Coastguard Worker - name - extension name 477*90277196SAndroid Build Coastguard Worker 478*90277196SAndroid Build Coastguard Worker Must implement.""" 479*90277196SAndroid Build Coastguard Worker raise NotImplementedError 480*90277196SAndroid Build Coastguard Worker 481*90277196SAndroid Build Coastguard Worker def extension_include_string(self, name): 482*90277196SAndroid Build Coastguard Worker """Return format string for include:: line for an extension appendix 483*90277196SAndroid Build Coastguard Worker file. 484*90277196SAndroid Build Coastguard Worker - name - extension name""" 485*90277196SAndroid Build Coastguard Worker 486*90277196SAndroid Build Coastguard Worker return 'include::{{appendices}}/{}[]'.format( 487*90277196SAndroid Build Coastguard Worker self.extension_file_path(name)) 488*90277196SAndroid Build Coastguard Worker 489*90277196SAndroid Build Coastguard Worker @property 490*90277196SAndroid Build Coastguard Worker def provisional_extension_warning(self): 491*90277196SAndroid Build Coastguard Worker """Return True if a warning should be included in extension 492*90277196SAndroid Build Coastguard Worker appendices for provisional extensions.""" 493*90277196SAndroid Build Coastguard Worker return True 494*90277196SAndroid Build Coastguard Worker 495*90277196SAndroid Build Coastguard Worker @property 496*90277196SAndroid Build Coastguard Worker def generated_include_path(self): 497*90277196SAndroid Build Coastguard Worker """Return path relative to the generated reference pages, to the 498*90277196SAndroid Build Coastguard Worker generated API include files.""" 499*90277196SAndroid Build Coastguard Worker 500*90277196SAndroid Build Coastguard Worker return '{generated}' 501*90277196SAndroid Build Coastguard Worker 502*90277196SAndroid Build Coastguard Worker @property 503*90277196SAndroid Build Coastguard Worker def include_extension_appendix_in_refpage(self): 504*90277196SAndroid Build Coastguard Worker """Return True if generating extension refpages by embedding 505*90277196SAndroid Build Coastguard Worker extension appendix content (default), False otherwise 506*90277196SAndroid Build Coastguard Worker (OpenXR).""" 507*90277196SAndroid Build Coastguard Worker 508*90277196SAndroid Build Coastguard Worker return True 509*90277196SAndroid Build Coastguard Worker 510*90277196SAndroid Build Coastguard Worker def valid_flag_bit(self, bitpos): 511*90277196SAndroid Build Coastguard Worker """Return True if bitpos is an allowed numeric bit position for 512*90277196SAndroid Build Coastguard Worker an API flag. 513*90277196SAndroid Build Coastguard Worker 514*90277196SAndroid Build Coastguard Worker Behavior depends on the data type used for flags (which may be 32 515*90277196SAndroid Build Coastguard Worker or 64 bits), and may depend on assumptions about compiler 516*90277196SAndroid Build Coastguard Worker handling of sign bits in enumerated types, as well.""" 517*90277196SAndroid Build Coastguard Worker return True 518*90277196SAndroid Build Coastguard Worker 519*90277196SAndroid Build Coastguard Worker @property 520*90277196SAndroid Build Coastguard Worker def duplicate_aliased_structs(self): 521*90277196SAndroid Build Coastguard Worker """ 522*90277196SAndroid Build Coastguard Worker Should aliased structs have the original struct definition listed in the 523*90277196SAndroid Build Coastguard Worker generated docs snippet? 524*90277196SAndroid Build Coastguard Worker """ 525*90277196SAndroid Build Coastguard Worker return False 526*90277196SAndroid Build Coastguard Worker 527*90277196SAndroid Build Coastguard Worker @property 528*90277196SAndroid Build Coastguard Worker def protectProtoComment(self): 529*90277196SAndroid Build Coastguard Worker """Return True if generated #endif should have a comment matching 530*90277196SAndroid Build Coastguard Worker the protection symbol used in the opening #ifdef/#ifndef.""" 531*90277196SAndroid Build Coastguard Worker return False 532*90277196SAndroid Build Coastguard Worker 533*90277196SAndroid Build Coastguard Worker @property 534*90277196SAndroid Build Coastguard Worker def extra_refpage_headers(self): 535*90277196SAndroid Build Coastguard Worker """Return any extra headers (preceding the title) for generated 536*90277196SAndroid Build Coastguard Worker reference pages.""" 537*90277196SAndroid Build Coastguard Worker return '' 538*90277196SAndroid Build Coastguard Worker 539*90277196SAndroid Build Coastguard Worker @property 540*90277196SAndroid Build Coastguard Worker def extra_refpage_body(self): 541*90277196SAndroid Build Coastguard Worker """Return any extra text (following the title) for generated 542*90277196SAndroid Build Coastguard Worker reference pages.""" 543*90277196SAndroid Build Coastguard Worker return '' 544*90277196SAndroid Build Coastguard Worker 545*90277196SAndroid Build Coastguard Worker def is_api_version_name(self, name): 546*90277196SAndroid Build Coastguard Worker """Return True if name is an API version name.""" 547*90277196SAndroid Build Coastguard Worker 548*90277196SAndroid Build Coastguard Worker return API_VERSION_NAME_RE.match(name) is not None 549*90277196SAndroid Build Coastguard Worker 550*90277196SAndroid Build Coastguard Worker @property 551*90277196SAndroid Build Coastguard Worker def docgen_language(self): 552*90277196SAndroid Build Coastguard Worker """Return the language to be used in docgenerator [source] 553*90277196SAndroid Build Coastguard Worker blocks.""" 554*90277196SAndroid Build Coastguard Worker 555*90277196SAndroid Build Coastguard Worker return 'c++' 556*90277196SAndroid Build Coastguard Worker 557*90277196SAndroid Build Coastguard Worker @property 558*90277196SAndroid Build Coastguard Worker def docgen_source_options(self): 559*90277196SAndroid Build Coastguard Worker """Return block options to be used in docgenerator [source] blocks, 560*90277196SAndroid Build Coastguard Worker which are appended to the 'source' block type. 561*90277196SAndroid Build Coastguard Worker Can be empty.""" 562*90277196SAndroid Build Coastguard Worker 563*90277196SAndroid Build Coastguard Worker return '%unbreakable' 564