1e5c31af7Sopenharmony_ci#!/usr/bin/python3 -i
2e5c31af7Sopenharmony_ci#
3e5c31af7Sopenharmony_ci# Copyright 2020-2024 The Khronos Group Inc.
4e5c31af7Sopenharmony_ci#
5e5c31af7Sopenharmony_ci# SPDX-License-Identifier: Apache-2.0
6e5c31af7Sopenharmony_ci
7e5c31af7Sopenharmony_ci# Description:
8e5c31af7Sopenharmony_ci# -----------
9e5c31af7Sopenharmony_ci# This script generates a .hpp file that can be included in an application
10e5c31af7Sopenharmony_ci# to generate json data that can then be used to generate the pipeline cache.
11e5c31af7Sopenharmony_ci
12e5c31af7Sopenharmony_ciimport os
13e5c31af7Sopenharmony_ciimport re
14e5c31af7Sopenharmony_cifrom generator import (GeneratorOptions, OutputGenerator, noneStr,
15e5c31af7Sopenharmony_ci                       regSortFeatures, write)
16e5c31af7Sopenharmony_ci
17e5c31af7Sopenharmony_cicopyright = """
18e5c31af7Sopenharmony_ci/*
19e5c31af7Sopenharmony_ci * Copyright 2021-2024 The Khronos Group Inc.
20e5c31af7Sopenharmony_ci *
21e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
22e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
23e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
24e5c31af7Sopenharmony_ci *
25e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
26e5c31af7Sopenharmony_ci *
27e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
28e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
29e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
30e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
31e5c31af7Sopenharmony_ci * limitations under the License.
32e5c31af7Sopenharmony_ci *
33e5c31af7Sopenharmony_ci *//*!
34e5c31af7Sopenharmony_ci * \\file
35e5c31af7Sopenharmony_ci * \\brief Defines JSON generators for Vulkan structures
36e5c31af7Sopenharmony_ci */
37e5c31af7Sopenharmony_ci"""
38e5c31af7Sopenharmony_ci
39e5c31af7Sopenharmony_cipredefinedCode = """
40e5c31af7Sopenharmony_ci/********************************************************************************************/
41e5c31af7Sopenharmony_ci/** This code is generated. To make changes, please modify the scripts or the relevant xml **/
42e5c31af7Sopenharmony_ci/********************************************************************************************/
43e5c31af7Sopenharmony_ci
44e5c31af7Sopenharmony_ci#include <iostream>
45e5c31af7Sopenharmony_ci#include <map>
46e5c31af7Sopenharmony_ci#include <bitset>
47e5c31af7Sopenharmony_ci#include <functional>
48e5c31af7Sopenharmony_ci#include <sstream>
49e5c31af7Sopenharmony_ci#include <cassert>
50e5c31af7Sopenharmony_ci#include <cmath>
51e5c31af7Sopenharmony_ci#ifndef VULKAN_JSON_CTS
52e5c31af7Sopenharmony_ci    #include <vulkan/vulkan.h>
53e5c31af7Sopenharmony_ci#endif
54e5c31af7Sopenharmony_ci
55e5c31af7Sopenharmony_ci#ifdef _WIN32
56e5c31af7Sopenharmony_ci	#ifndef WIN32_LEAN_AND_MEAN
57e5c31af7Sopenharmony_ci	#define WIN32_LEAN_AND_MEAN
58e5c31af7Sopenharmony_ci	#endif
59e5c31af7Sopenharmony_ci	#define VC_EXTRALEAN
60e5c31af7Sopenharmony_ci	#define NOMINMAX
61e5c31af7Sopenharmony_ci	#include <windows.h>
62e5c31af7Sopenharmony_ci#endif
63e5c31af7Sopenharmony_ci
64e5c31af7Sopenharmony_cinamespace vk_json {
65e5c31af7Sopenharmony_ci
66e5c31af7Sopenharmony_cistatic thread_local int s_num_spaces    = 0;
67e5c31af7Sopenharmony_cistatic thread_local std::stringstream _string_stream;
68e5c31af7Sopenharmony_ci
69e5c31af7Sopenharmony_cistatic void dumpPNextChain(const void* pNext);
70e5c31af7Sopenharmony_ci
71e5c31af7Sopenharmony_ci// By default, redirect to std::cout. Can stream it to a stringstream if needed.
72e5c31af7Sopenharmony_ci//#define   _OUT std::cout
73e5c31af7Sopenharmony_ci#define _OUT _string_stream
74e5c31af7Sopenharmony_ci
75e5c31af7Sopenharmony_ci// Helper utility to do indentation in the generated json file.
76e5c31af7Sopenharmony_ci#define PRINT_SPACE for (int k = 0; k < s_num_spaces; k++) _OUT << \" \";
77e5c31af7Sopenharmony_ci
78e5c31af7Sopenharmony_ci#define INDENT(sz) s_num_spaces += (sz);
79e5c31af7Sopenharmony_ci
80e5c31af7Sopenharmony_ci#define PRINT_VAL(c) PRINT_SPACE \\
81e5c31af7Sopenharmony_ci    if (s != "") {\\
82e5c31af7Sopenharmony_ci        _OUT << \"\\\"\" << s << \"\\\"\" << \" : \" << o << (c ? \",\" : \"\") << std::endl; \\
83e5c31af7Sopenharmony_ci    } else {\\
84e5c31af7Sopenharmony_ci        _OUT << o << (c ? \",\" : \"\") << std::endl; \\
85e5c31af7Sopenharmony_ci    }
86e5c31af7Sopenharmony_ci
87e5c31af7Sopenharmony_ci#define PRINT_STR(c) PRINT_SPACE \\
88e5c31af7Sopenharmony_ci    if (s != "") {\\
89e5c31af7Sopenharmony_ci        _OUT << \"\\\"\" << s << \"\\\"\" << \" : " << \"\\\"\" << o << \"\\\"\" << (c ? \",\" : \"\") << std::endl; \\
90e5c31af7Sopenharmony_ci    } else {\\
91e5c31af7Sopenharmony_ci        _OUT << \"\\\"\" << o << \"\\\"\" << (c ? \",\" : \"\") << std::endl; \\
92e5c31af7Sopenharmony_ci    }
93e5c31af7Sopenharmony_ci
94e5c31af7Sopenharmony_ci// To make sure the generated data is consistent across platforms,
95e5c31af7Sopenharmony_ci// we typecast to 32-bit and dump the data.
96e5c31af7Sopenharmony_ci// The value is not expected to exceed the range.
97e5c31af7Sopenharmony_cistatic void print_size_t(const size_t* o, const std::string& s, bool commaNeeded=true)
98e5c31af7Sopenharmony_ci{
99e5c31af7Sopenharmony_ci    PRINT_SPACE
100e5c31af7Sopenharmony_ci    _OUT << \"\\\"\" << s << \"\\\"\" << \" : \" << static_cast<%s>(*o) << (commaNeeded ? \",\" : \"\") << std::endl;\\
101e5c31af7Sopenharmony_ci}
102e5c31af7Sopenharmony_cistatic void print_size_t(size_t o, const std::string& s, bool commaNeeded=true)
103e5c31af7Sopenharmony_ci{
104e5c31af7Sopenharmony_ci    PRINT_SPACE
105e5c31af7Sopenharmony_ci    _OUT << \"\\\"\" << s << \"\\\"\" << \" : \" << static_cast<%s>(o) << (commaNeeded ? \",\" : \"\") << std::endl;\\
106e5c31af7Sopenharmony_ci}
107e5c31af7Sopenharmony_ci"""
108e5c31af7Sopenharmony_ci
109e5c31af7Sopenharmony_ciheaderGuardTop = """#ifndef _VULKAN_JSON_DATA_HPP
110e5c31af7Sopenharmony_ci#define _VULKAN_JSON_DATA_HPP
111e5c31af7Sopenharmony_ci"""
112e5c31af7Sopenharmony_ci
113e5c31af7Sopenharmony_ciheaderGuardBottom = """#endif // _VULKAN_JSON_DATA_HPP"""
114e5c31af7Sopenharmony_ci
115e5c31af7Sopenharmony_ciencodeBase64CodeCTS = """
116e5c31af7Sopenharmony_ci// Base 64 formatter class from executor/xeTestLogWriter.cpp
117e5c31af7Sopenharmony_ci
118e5c31af7Sopenharmony_ciclass Base64Formatter
119e5c31af7Sopenharmony_ci{
120e5c31af7Sopenharmony_cipublic:
121e5c31af7Sopenharmony_ci	const deUint8*	data;
122e5c31af7Sopenharmony_ci	int				numBytes;
123e5c31af7Sopenharmony_ci
124e5c31af7Sopenharmony_ci	Base64Formatter(const deUint8* data_, int numBytes_) : data(data_), numBytes(numBytes_) {}
125e5c31af7Sopenharmony_ci};
126e5c31af7Sopenharmony_ci
127e5c31af7Sopenharmony_cistd::ostream& operator<< (std::ostream& str, const Base64Formatter& fmt)
128e5c31af7Sopenharmony_ci{
129e5c31af7Sopenharmony_ci	static const char s_base64Table[64] =
130e5c31af7Sopenharmony_ci	{
131e5c31af7Sopenharmony_ci		'A','B','C','D','E','F','G','H','I','J','K','L','M',
132e5c31af7Sopenharmony_ci		'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
133e5c31af7Sopenharmony_ci		'a','b','c','d','e','f','g','h','i','j','k','l','m',
134e5c31af7Sopenharmony_ci		'n','o','p','q','r','s','t','u','v','w','x','y','z',
135e5c31af7Sopenharmony_ci		'0','1','2','3','4','5','6','7','8','9','+','/'
136e5c31af7Sopenharmony_ci	};
137e5c31af7Sopenharmony_ci
138e5c31af7Sopenharmony_ci	const deUint8*	data = fmt.data;
139e5c31af7Sopenharmony_ci	int				numBytes = fmt.numBytes;
140e5c31af7Sopenharmony_ci	int				srcNdx = 0;
141e5c31af7Sopenharmony_ci
142e5c31af7Sopenharmony_ci	DE_ASSERT(data && (numBytes > 0));
143e5c31af7Sopenharmony_ci
144e5c31af7Sopenharmony_ci	/* Loop all input chars. */
145e5c31af7Sopenharmony_ci	while (srcNdx < numBytes)
146e5c31af7Sopenharmony_ci	{
147e5c31af7Sopenharmony_ci		int		numRead = de::min(3, numBytes - srcNdx);
148e5c31af7Sopenharmony_ci		deUint8	s0 = data[srcNdx];
149e5c31af7Sopenharmony_ci		deUint8	s1 = (numRead >= 2) ? data[srcNdx + 1] : 0;
150e5c31af7Sopenharmony_ci		deUint8	s2 = (numRead >= 3) ? data[srcNdx + 2] : 0;
151e5c31af7Sopenharmony_ci		char	d[4];
152e5c31af7Sopenharmony_ci
153e5c31af7Sopenharmony_ci		srcNdx += numRead;
154e5c31af7Sopenharmony_ci
155e5c31af7Sopenharmony_ci		d[0] = s_base64Table[s0 >> 2];
156e5c31af7Sopenharmony_ci		d[1] = s_base64Table[((s0 & 0x3) << 4) | (s1 >> 4)];
157e5c31af7Sopenharmony_ci		d[2] = s_base64Table[((s1 & 0xF) << 2) | (s2 >> 6)];
158e5c31af7Sopenharmony_ci		d[3] = s_base64Table[s2 & 0x3F];
159e5c31af7Sopenharmony_ci
160e5c31af7Sopenharmony_ci		if (numRead < 3) d[3] = '=';
161e5c31af7Sopenharmony_ci		if (numRead < 2) d[2] = '=';
162e5c31af7Sopenharmony_ci
163e5c31af7Sopenharmony_ci		/* Write data. */
164e5c31af7Sopenharmony_ci		str.write(&d[0], sizeof(d));
165e5c31af7Sopenharmony_ci	}
166e5c31af7Sopenharmony_ci
167e5c31af7Sopenharmony_ci	return str;
168e5c31af7Sopenharmony_ci}
169e5c31af7Sopenharmony_ci
170e5c31af7Sopenharmony_ciinline Base64Formatter toBase64(const deUint8* bytes, int numBytes) {return Base64Formatter(bytes, numBytes); }
171e5c31af7Sopenharmony_ci
172e5c31af7Sopenharmony_cistatic void print_void_data(const void * o, int oSize, const std::string& s, bool commaNeeded=true)
173e5c31af7Sopenharmony_ci{
174e5c31af7Sopenharmony_ci	if (o != NULL && oSize != 0)
175e5c31af7Sopenharmony_ci	{
176e5c31af7Sopenharmony_ci		PRINT_SPACE _OUT << "\\\"" << s << "\\\"" << " : " << "\\\"" << toBase64((deUint8*)o, oSize) << "\\\"" << (commaNeeded ? "," : "") << std::endl;
177e5c31af7Sopenharmony_ci	}
178e5c31af7Sopenharmony_ci	else
179e5c31af7Sopenharmony_ci	{
180e5c31af7Sopenharmony_ci		PRINT_SPACE _OUT << "\\\"" << s << "\\\"" << " : " << "\\\"NULL\\\"" << (commaNeeded ? "," : "") << std::endl;
181e5c31af7Sopenharmony_ci	}
182e5c31af7Sopenharmony_ci}
183e5c31af7Sopenharmony_ci"""
184e5c31af7Sopenharmony_ciencodeBase64Code = """
185e5c31af7Sopenharmony_ci// Base 64 formatter class from executor/xeTestLogWriter.cpp
186e5c31af7Sopenharmony_ci
187e5c31af7Sopenharmony_ciclass Base64Formatter
188e5c31af7Sopenharmony_ci{
189e5c31af7Sopenharmony_cipublic:
190e5c31af7Sopenharmony_ci	const uint8_t*	data;
191e5c31af7Sopenharmony_ci	int				numBytes;
192e5c31af7Sopenharmony_ci
193e5c31af7Sopenharmony_ci	Base64Formatter(const uint8_t* data_, int numBytes_) : data(data_), numBytes(numBytes_) {}
194e5c31af7Sopenharmony_ci};
195e5c31af7Sopenharmony_ci
196e5c31af7Sopenharmony_cistd::ostream& operator<< (std::ostream& str, const Base64Formatter& fmt)
197e5c31af7Sopenharmony_ci{
198e5c31af7Sopenharmony_ci	static const char s_base64Table[64] =
199e5c31af7Sopenharmony_ci	{
200e5c31af7Sopenharmony_ci		'A','B','C','D','E','F','G','H','I','J','K','L','M',
201e5c31af7Sopenharmony_ci		'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
202e5c31af7Sopenharmony_ci		'a','b','c','d','e','f','g','h','i','j','k','l','m',
203e5c31af7Sopenharmony_ci		'n','o','p','q','r','s','t','u','v','w','x','y','z',
204e5c31af7Sopenharmony_ci		'0','1','2','3','4','5','6','7','8','9','+','/'
205e5c31af7Sopenharmony_ci	};
206e5c31af7Sopenharmony_ci
207e5c31af7Sopenharmony_ci	const uint8_t*	data = fmt.data;
208e5c31af7Sopenharmony_ci	int				numBytes = fmt.numBytes;
209e5c31af7Sopenharmony_ci	int				srcNdx = 0;
210e5c31af7Sopenharmony_ci
211e5c31af7Sopenharmony_ci	assert(data && (numBytes > 0));
212e5c31af7Sopenharmony_ci
213e5c31af7Sopenharmony_ci	/* Loop all input chars. */
214e5c31af7Sopenharmony_ci	while (srcNdx < numBytes)
215e5c31af7Sopenharmony_ci	{
216e5c31af7Sopenharmony_ci        #undef min
217e5c31af7Sopenharmony_ci		int		numRead = std::min(3, numBytes - srcNdx);
218e5c31af7Sopenharmony_ci		uint8_t	s0 = data[srcNdx];
219e5c31af7Sopenharmony_ci		uint8_t	s1 = (numRead >= 2) ? data[srcNdx + 1] : 0;
220e5c31af7Sopenharmony_ci		uint8_t	s2 = (numRead >= 3) ? data[srcNdx + 2] : 0;
221e5c31af7Sopenharmony_ci		char	d[4];
222e5c31af7Sopenharmony_ci
223e5c31af7Sopenharmony_ci		srcNdx += numRead;
224e5c31af7Sopenharmony_ci
225e5c31af7Sopenharmony_ci		d[0] = s_base64Table[s0 >> 2];
226e5c31af7Sopenharmony_ci		d[1] = s_base64Table[((s0 & 0x3) << 4) | (s1 >> 4)];
227e5c31af7Sopenharmony_ci		d[2] = s_base64Table[((s1 & 0xF) << 2) | (s2 >> 6)];
228e5c31af7Sopenharmony_ci		d[3] = s_base64Table[s2 & 0x3F];
229e5c31af7Sopenharmony_ci
230e5c31af7Sopenharmony_ci		if (numRead < 3) d[3] = '=';
231e5c31af7Sopenharmony_ci		if (numRead < 2) d[2] = '=';
232e5c31af7Sopenharmony_ci
233e5c31af7Sopenharmony_ci		/* Write data. */
234e5c31af7Sopenharmony_ci		str.write(&d[0], sizeof(d));
235e5c31af7Sopenharmony_ci	}
236e5c31af7Sopenharmony_ci
237e5c31af7Sopenharmony_ci	return str;
238e5c31af7Sopenharmony_ci}
239e5c31af7Sopenharmony_ci
240e5c31af7Sopenharmony_ciinline Base64Formatter toBase64(const uint8_t* bytes, int numBytes) {return Base64Formatter(bytes, numBytes); }
241e5c31af7Sopenharmony_ci
242e5c31af7Sopenharmony_cistatic void print_void_data(const void * o, int oSize, const std::string& s, bool commaNeeded=true)
243e5c31af7Sopenharmony_ci{
244e5c31af7Sopenharmony_ci	if (o != NULL && oSize != 0)
245e5c31af7Sopenharmony_ci	{
246e5c31af7Sopenharmony_ci		PRINT_SPACE _OUT << "\\\"" << s << "\\\"" << " : " << "\\\"" << toBase64((uint8_t*)o, oSize) << "\\\"" << (commaNeeded ? "," : "") << std::endl;
247e5c31af7Sopenharmony_ci	}
248e5c31af7Sopenharmony_ci	else
249e5c31af7Sopenharmony_ci	{
250e5c31af7Sopenharmony_ci		PRINT_SPACE _OUT << "\\\"" << s << "\\\"" << " : " << "\\\"NULL\\\"" << (commaNeeded ? "," : "") << std::endl;
251e5c31af7Sopenharmony_ci	}
252e5c31af7Sopenharmony_ci}
253e5c31af7Sopenharmony_ci"""
254e5c31af7Sopenharmony_ci
255e5c31af7Sopenharmony_ciclass JSONGeneratorOptions(GeneratorOptions):
256e5c31af7Sopenharmony_ci    """JSONGeneratorOptions - subclass of GeneratorOptions.
257e5c31af7Sopenharmony_ci
258e5c31af7Sopenharmony_ci    Adds options used by JSONOutputGenerator objects during C language header
259e5c31af7Sopenharmony_ci    generation."""
260e5c31af7Sopenharmony_ci
261e5c31af7Sopenharmony_ci    def __init__(self,
262e5c31af7Sopenharmony_ci                 prefixText="",
263e5c31af7Sopenharmony_ci                 genFuncPointers=True,
264e5c31af7Sopenharmony_ci                 protectFile=True,
265e5c31af7Sopenharmony_ci                 protectFeature=True,
266e5c31af7Sopenharmony_ci                 protectProto=None,
267e5c31af7Sopenharmony_ci                 protectProtoStr=None,
268e5c31af7Sopenharmony_ci                 apicall='',
269e5c31af7Sopenharmony_ci                 apientry='',
270e5c31af7Sopenharmony_ci                 apientryp='',
271e5c31af7Sopenharmony_ci                 isCTS = False,
272e5c31af7Sopenharmony_ci                 indentFuncProto=True,
273e5c31af7Sopenharmony_ci                 indentFuncPointer=False,
274e5c31af7Sopenharmony_ci                 alignFuncParam=0,
275e5c31af7Sopenharmony_ci                 genEnumBeginEndRange=False,
276e5c31af7Sopenharmony_ci                 genAliasMacro=False,
277e5c31af7Sopenharmony_ci                 aliasMacro='',
278e5c31af7Sopenharmony_ci                 vulkanLayer=False,
279e5c31af7Sopenharmony_ci                 **kwargs
280e5c31af7Sopenharmony_ci                 ):
281e5c31af7Sopenharmony_ci
282e5c31af7Sopenharmony_ci        GeneratorOptions.__init__(self, **kwargs)
283e5c31af7Sopenharmony_ci        self.isCTS = isCTS
284e5c31af7Sopenharmony_ci
285e5c31af7Sopenharmony_ci        self.vulkanLayer = vulkanLayer
286e5c31af7Sopenharmony_ci
287e5c31af7Sopenharmony_ciclass JSONOutputGenerator(OutputGenerator):
288e5c31af7Sopenharmony_ci    # This is an ordered list of sections in the header file.
289e5c31af7Sopenharmony_ci    TYPE_SECTIONS = ['basetype', 'handle', 'enum',
290e5c31af7Sopenharmony_ci                     'group', 'bitmask', 'struct']
291e5c31af7Sopenharmony_ci    ALL_SECTIONS = TYPE_SECTIONS
292e5c31af7Sopenharmony_ci
293e5c31af7Sopenharmony_ci    def __init__(self, *args, **kwargs):
294e5c31af7Sopenharmony_ci        super().__init__(*args, **kwargs)
295e5c31af7Sopenharmony_ci        # Internal state - accumulators for different inner block text
296e5c31af7Sopenharmony_ci        self.sections = {section: [] for section in self.ALL_SECTIONS}
297e5c31af7Sopenharmony_ci        self.feature_not_empty = False
298e5c31af7Sopenharmony_ci        self.may_alias         = None
299e5c31af7Sopenharmony_ci        self.vkscFeatureList   = []
300e5c31af7Sopenharmony_ci        self.vkFeatureLayerList = []
301e5c31af7Sopenharmony_ci
302e5c31af7Sopenharmony_ci        # Fills in some extensions for exclusion while generating code for layer.
303e5c31af7Sopenharmony_ci        self.vkLayerNotReqList = set([""])
304e5c31af7Sopenharmony_ci
305e5c31af7Sopenharmony_ci        self.platformList      = ["xlib",
306e5c31af7Sopenharmony_ci                                  "xlib_xrandr",
307e5c31af7Sopenharmony_ci                                  "xcb",
308e5c31af7Sopenharmony_ci                                  "wayland",
309e5c31af7Sopenharmony_ci                                  "directfb",
310e5c31af7Sopenharmony_ci                                  "android",
311e5c31af7Sopenharmony_ci                                  "win32",
312e5c31af7Sopenharmony_ci                                  "vi",
313e5c31af7Sopenharmony_ci                                  "ios",
314e5c31af7Sopenharmony_ci                                  "macos",
315e5c31af7Sopenharmony_ci                                  "metal",
316e5c31af7Sopenharmony_ci                                  "fuchsia",
317e5c31af7Sopenharmony_ci                                  "ggp",
318e5c31af7Sopenharmony_ci                                  "QNX",
319e5c31af7Sopenharmony_ci                                  "provisional"]
320e5c31af7Sopenharmony_ci        self.baseTypeList      = ["int32_t",
321e5c31af7Sopenharmony_ci                                  "uint32_t",
322e5c31af7Sopenharmony_ci                                  "uint8_t",
323e5c31af7Sopenharmony_ci                                  "uint64_t",
324e5c31af7Sopenharmony_ci                                  "float",
325e5c31af7Sopenharmony_ci                                  "int",
326e5c31af7Sopenharmony_ci                                  "double",
327e5c31af7Sopenharmony_ci                                  "int64_t",
328e5c31af7Sopenharmony_ci                                  "uint16_t",
329e5c31af7Sopenharmony_ci                                  "char"]
330e5c31af7Sopenharmony_ci
331e5c31af7Sopenharmony_ci    def printBaseTypes(self):
332e5c31af7Sopenharmony_ci        for baseType in self.baseTypeList:
333e5c31af7Sopenharmony_ci            printStr = "    PRINT_VAL(commaNeeded)\n"
334e5c31af7Sopenharmony_ci
335e5c31af7Sopenharmony_ci            # Some special handling needed here.
336e5c31af7Sopenharmony_ci            if baseType == 'char':
337e5c31af7Sopenharmony_ci                write("static void print_%s(const %s * const* o, const std::string& s, bool commaNeeded=true)\n" %(baseType, self.baseTypeListMap[baseType]) +
338e5c31af7Sopenharmony_ci                  "{\n"                                                                                                           						+
339e5c31af7Sopenharmony_ci                  "    PRINT_STR(commaNeeded)\n"                                                                                  						+
340e5c31af7Sopenharmony_ci                  "}\n"
341e5c31af7Sopenharmony_ci                  , file=self.outFile
342e5c31af7Sopenharmony_ci                 )
343e5c31af7Sopenharmony_ci
344e5c31af7Sopenharmony_ci            if self.isCTS and baseType == "float":
345e5c31af7Sopenharmony_ci                printStr = "	if (std::isnan(o))\n"
346e5c31af7Sopenharmony_ci                printStr +="	{\n"
347e5c31af7Sopenharmony_ci                printStr +="		PRINT_SPACE\n"
348e5c31af7Sopenharmony_ci                printStr +="		if (s != \"\")\n"
349e5c31af7Sopenharmony_ci                printStr +="			_OUT << \"\\\"\" << s << \"\\\"\" << \" : \\\"NaN\\\"\" << (commaNeeded ? \",\" : \"\") << std::endl;\n"
350e5c31af7Sopenharmony_ci                printStr +="		else\n"
351e5c31af7Sopenharmony_ci                printStr +="			_OUT << \"\\\"NaN\\\"\" << (commaNeeded ? \",\" : \"\") << std::endl;\n"
352e5c31af7Sopenharmony_ci                printStr +="	}\n"
353e5c31af7Sopenharmony_ci                printStr +="	else\n"
354e5c31af7Sopenharmony_ci                printStr +="	{\n"
355e5c31af7Sopenharmony_ci                printStr +="		PRINT_VAL(commaNeeded)\n"
356e5c31af7Sopenharmony_ci                printStr +="	}\n"
357e5c31af7Sopenharmony_ci
358e5c31af7Sopenharmony_ci            write("static void print_%s(%s o, const std::string& s, bool commaNeeded=true)\n" %(baseType, self.baseTypeListMap[baseType]) +
359e5c31af7Sopenharmony_ci                  "{\n"                                                                                        						 +
360e5c31af7Sopenharmony_ci                  printStr                                                                                     						 +
361e5c31af7Sopenharmony_ci                  "}\n"
362e5c31af7Sopenharmony_ci                  , file=self.outFile
363e5c31af7Sopenharmony_ci                  )
364e5c31af7Sopenharmony_ci
365e5c31af7Sopenharmony_ci            if baseType == 'char':
366e5c31af7Sopenharmony_ci                printStr = "    PRINT_STR(commaNeeded)\n"
367e5c31af7Sopenharmony_ci
368e5c31af7Sopenharmony_ci            if self.isCTS and baseType == "float":
369e5c31af7Sopenharmony_ci                printStr = "	if (std::isnan(*o))\n"
370e5c31af7Sopenharmony_ci                printStr +="	{\n"
371e5c31af7Sopenharmony_ci                printStr +="		PRINT_SPACE\n"
372e5c31af7Sopenharmony_ci                printStr +="		if (s != \"\")\n"
373e5c31af7Sopenharmony_ci                printStr +="			_OUT << \"\\\"\" << s << \"\\\"\" << \" : \\\"NaN\\\"\" << (commaNeeded ? \",\" : \"\") << std::endl;\n"
374e5c31af7Sopenharmony_ci                printStr +="		else\n"
375e5c31af7Sopenharmony_ci                printStr +="			_OUT << \"\\\"NaN\\\"\" << (commaNeeded ? \",\" : \"\") << std::endl;\n"
376e5c31af7Sopenharmony_ci                printStr +="	}\n"
377e5c31af7Sopenharmony_ci                printStr +="	else\n"
378e5c31af7Sopenharmony_ci                printStr +="	{\n"
379e5c31af7Sopenharmony_ci                printStr +="		PRINT_VAL(commaNeeded)\n"
380e5c31af7Sopenharmony_ci                printStr +="	}\n"
381e5c31af7Sopenharmony_ci
382e5c31af7Sopenharmony_ci            write("static void print_%s(const %s * o, const std::string& s, bool commaNeeded=true)\n" %(baseType, self.baseTypeListMap[baseType]) +
383e5c31af7Sopenharmony_ci                  "{\n"                                                                                                						 +
384e5c31af7Sopenharmony_ci                  printStr                                                                                             						 +
385e5c31af7Sopenharmony_ci                  "}\n"
386e5c31af7Sopenharmony_ci                  , file=self.outFile
387e5c31af7Sopenharmony_ci                 )
388e5c31af7Sopenharmony_ci
389e5c31af7Sopenharmony_ci    def createLayerUnusedList(self):
390e5c31af7Sopenharmony_ci        allExtensions = self.registry.reg.findall('extensions')
391e5c31af7Sopenharmony_ci        for extensions in allExtensions:
392e5c31af7Sopenharmony_ci            extensionList = extensions.findall("extension")
393e5c31af7Sopenharmony_ci            for extension in extensionList:
394e5c31af7Sopenharmony_ci                for platform in self.platformList:
395e5c31af7Sopenharmony_ci                    if re.search(platform, extension.get("name"), re.IGNORECASE):
396e5c31af7Sopenharmony_ci                        requiredList = extension.findall("require")
397e5c31af7Sopenharmony_ci                        for requiredItem in requiredList:
398e5c31af7Sopenharmony_ci                            typeList = requiredItem.findall("type")
399e5c31af7Sopenharmony_ci                            for typeName in typeList:
400e5c31af7Sopenharmony_ci                                if platform == "vi":
401e5c31af7Sopenharmony_ci                                    if re.search("NN", extension.get("name")):
402e5c31af7Sopenharmony_ci                                        self.vkLayerNotReqList.add(typeName.get("name"))
403e5c31af7Sopenharmony_ci                                else:
404e5c31af7Sopenharmony_ci                                    self.vkLayerNotReqList.add(typeName.get("name"))
405e5c31af7Sopenharmony_ci                        break
406e5c31af7Sopenharmony_ci
407e5c31af7Sopenharmony_ci        typesList = self.registry.reg.findall('types')
408e5c31af7Sopenharmony_ci        for types in typesList:
409e5c31af7Sopenharmony_ci            typeList = types.findall("type")
410e5c31af7Sopenharmony_ci            for type in typeList:
411e5c31af7Sopenharmony_ci                if type.get("name") != "":
412e5c31af7Sopenharmony_ci                    cat  = type.get("category")
413e5c31af7Sopenharmony_ci                    name = type.get("name")
414e5c31af7Sopenharmony_ci                    if cat in {"handle", "bitmask", "basetype", "enum", "struct"}:
415e5c31af7Sopenharmony_ci                        for platform in self.platformList:
416e5c31af7Sopenharmony_ci                            if re.search(platform, name, re.IGNORECASE):
417e5c31af7Sopenharmony_ci                                if platform == "vi":
418e5c31af7Sopenharmony_ci                                    if re.search("NN", name):
419e5c31af7Sopenharmony_ci                                        self.vkLayerNotReqList.add(name)
420e5c31af7Sopenharmony_ci                                else:
421e5c31af7Sopenharmony_ci                                    self.vkLayerNotReqList.add(name)
422e5c31af7Sopenharmony_ci                                break
423e5c31af7Sopenharmony_ci
424e5c31af7Sopenharmony_ci
425e5c31af7Sopenharmony_ci    def createvkscFeatureList(self):
426e5c31af7Sopenharmony_ci        for feature in self.registry.reg.findall('feature'):
427e5c31af7Sopenharmony_ci            if feature.get('api').find('vulkansc') != -1:
428e5c31af7Sopenharmony_ci                # Remove entries that are removed in features in VKSC profile.
429e5c31af7Sopenharmony_ci                requiredList = feature.findall("require")
430e5c31af7Sopenharmony_ci
431e5c31af7Sopenharmony_ci                for requiredItem in requiredList:
432e5c31af7Sopenharmony_ci                    typeList = requiredItem.findall("type")
433e5c31af7Sopenharmony_ci                    for typeName in typeList:
434e5c31af7Sopenharmony_ci                        if typeName.get("name") != "":
435e5c31af7Sopenharmony_ci                            self.vkscFeatureList.append(typeName.get("name"))
436e5c31af7Sopenharmony_ci
437e5c31af7Sopenharmony_ci                removeItemList = feature.findall("remove")
438e5c31af7Sopenharmony_ci                for removeItem in removeItemList:
439e5c31af7Sopenharmony_ci                    removeTypes = removeItem.findall("type")
440e5c31af7Sopenharmony_ci                    for item in removeTypes:
441e5c31af7Sopenharmony_ci                        if self.vkscFeatureList.count(item.get("name")) > 0:
442e5c31af7Sopenharmony_ci                            self.vkscFeatureList.remove(item.get("name"))
443e5c31af7Sopenharmony_ci
444e5c31af7Sopenharmony_ci        allExtensions = self.registry.reg.findall('extensions')
445e5c31af7Sopenharmony_ci        for extensions in allExtensions:
446e5c31af7Sopenharmony_ci            extensionList = extensions.findall("extension")
447e5c31af7Sopenharmony_ci            for extension in extensionList:
448e5c31af7Sopenharmony_ci                if extension.get("supported").find("vulkansc") != -1:
449e5c31af7Sopenharmony_ci                    requiredList = extension.findall("require")
450e5c31af7Sopenharmony_ci                    for requiredItem in requiredList:
451e5c31af7Sopenharmony_ci                        typeList = requiredItem.findall("type")
452e5c31af7Sopenharmony_ci                        for typeName in typeList:
453e5c31af7Sopenharmony_ci                            self.vkscFeatureList.append(typeName.get("name"))
454e5c31af7Sopenharmony_ci
455e5c31af7Sopenharmony_ci    def printPrototypesAndExtensionDump(self):
456e5c31af7Sopenharmony_ci        code = ""
457e5c31af7Sopenharmony_ci
458e5c31af7Sopenharmony_ci        code += "/*************************************** Begin prototypes ***********************************/\n"
459e5c31af7Sopenharmony_ci        if self.vulkanLayer:
460e5c31af7Sopenharmony_ci            typesList = self.registry.reg.findall('types')
461e5c31af7Sopenharmony_ci            for types in typesList:
462e5c31af7Sopenharmony_ci                typeList = types.findall("type")
463e5c31af7Sopenharmony_ci                for type in typeList:
464e5c31af7Sopenharmony_ci                    if type.get("name") != "":
465e5c31af7Sopenharmony_ci                        cat  = type.get("category")
466e5c31af7Sopenharmony_ci                        name = type.get("name")
467e5c31af7Sopenharmony_ci
468e5c31af7Sopenharmony_ci            enumList = self.registry.reg.findall('enums')
469e5c31af7Sopenharmony_ci            for enums in enumList:
470e5c31af7Sopenharmony_ci                name = enums.get("name")
471e5c31af7Sopenharmony_ci        else:
472e5c31af7Sopenharmony_ci            typesList = self.registry.reg.findall('types')
473e5c31af7Sopenharmony_ci            for types in typesList:
474e5c31af7Sopenharmony_ci                typeList = types.findall("type")
475e5c31af7Sopenharmony_ci                for type in typeList:
476e5c31af7Sopenharmony_ci                    if type.get("name") != "":
477e5c31af7Sopenharmony_ci                        cat  = type.get("category")
478e5c31af7Sopenharmony_ci                        name = type.get("name")
479e5c31af7Sopenharmony_ci
480e5c31af7Sopenharmony_ci        code += "/*************************************** End prototypes ***********************************/\n\n"
481e5c31af7Sopenharmony_ci        code += "static void dumpPNextChain(const void* pNext) {\n"
482e5c31af7Sopenharmony_ci        code += "      VkBaseInStructure *pBase = (VkBaseInStructure*)pNext;\n"
483e5c31af7Sopenharmony_ci        code += "      if (pNext) {\n"
484e5c31af7Sopenharmony_ci        code += "           PRINT_SPACE\n"
485e5c31af7Sopenharmony_ci        code += "           _OUT << \"\\\"pNext\\\":\"<< std::endl;\n\n"
486e5c31af7Sopenharmony_ci        code += "          switch (pBase->sType) {\n"
487e5c31af7Sopenharmony_ci
488e5c31af7Sopenharmony_ci        for type in typeList:
489e5c31af7Sopenharmony_ci            if type.get('category') == 'struct' and type.get('structextends') is not None:
490e5c31af7Sopenharmony_ci                if (self.vulkanLayer and (type.get('name') not in self.vkLayerNotReqList)) or (not self.vulkanLayer):
491e5c31af7Sopenharmony_ci                    members = type.findall('member')
492e5c31af7Sopenharmony_ci                    for m in members:
493e5c31af7Sopenharmony_ci                            n = type.get('name')
494e5c31af7Sopenharmony_ci                            if m.get('values') and (n in self.vkFeatureLayerList):
495e5c31af7Sopenharmony_ci                                code += "             case %s:" %(m.get('values'))
496e5c31af7Sopenharmony_ci                                code += "print_%s((%s *) pNext, \"%s\", true);\n" %(n, n, n)
497e5c31af7Sopenharmony_ci                                code += "             break;\n"
498e5c31af7Sopenharmony_ci
499e5c31af7Sopenharmony_ci        code += "             default: assert(false); // No structure type matching\n"
500e5c31af7Sopenharmony_ci        code += "         }\n"
501e5c31af7Sopenharmony_ci        code += "     }\n"
502e5c31af7Sopenharmony_ci        code += "  }\n"
503e5c31af7Sopenharmony_ci
504e5c31af7Sopenharmony_ci        return code
505e5c31af7Sopenharmony_ci
506e5c31af7Sopenharmony_ci
507e5c31af7Sopenharmony_ci    def beginFile(self, genOpts):
508e5c31af7Sopenharmony_ci        OutputGenerator.beginFile(self, genOpts)
509e5c31af7Sopenharmony_ci
510e5c31af7Sopenharmony_ci        self.vulkanLayer = genOpts.vulkanLayer
511e5c31af7Sopenharmony_ci        if self.vulkanLayer:
512e5c31af7Sopenharmony_ci            self.createLayerUnusedList()
513e5c31af7Sopenharmony_ci
514e5c31af7Sopenharmony_ci        self.createvkscFeatureList()
515e5c31af7Sopenharmony_ci
516e5c31af7Sopenharmony_ci        self.isCTS = genOpts.isCTS
517e5c31af7Sopenharmony_ci
518e5c31af7Sopenharmony_ci        self.baseTypeListMap  = {
519e5c31af7Sopenharmony_ci                                  "int32_t"   : "deInt32" if self.isCTS else "int32_t",
520e5c31af7Sopenharmony_ci                                  "uint32_t"  : "deUint32" if self.isCTS else "uint32_t",
521e5c31af7Sopenharmony_ci                                  "uint8_t"   : "deUint8" if self.isCTS else "uint8_t",
522e5c31af7Sopenharmony_ci                                  "uint64_t"  : "deUint64" if self.isCTS else "uint64_t",
523e5c31af7Sopenharmony_ci                                  "float"     : "float",
524e5c31af7Sopenharmony_ci                                  "int"       : "int",
525e5c31af7Sopenharmony_ci                                  "double"    : "double",
526e5c31af7Sopenharmony_ci                                  "int64_t"   : "deInt64" if self.isCTS else "int64_t",
527e5c31af7Sopenharmony_ci                                  "uint16_t"  : "deUint16" if self.isCTS else "uint16_t",
528e5c31af7Sopenharmony_ci                                  "char"      : "char"
529e5c31af7Sopenharmony_ci                                }
530e5c31af7Sopenharmony_ci
531e5c31af7Sopenharmony_ci        write(headerGuardTop, file=self.outFile, end='')
532e5c31af7Sopenharmony_ci        write(copyright, file=self.outFile)
533e5c31af7Sopenharmony_ci        if self.isCTS:
534e5c31af7Sopenharmony_ci            write(predefinedCode % ("deUint32", "deUint32"), file=self.outFile)
535e5c31af7Sopenharmony_ci        else:
536e5c31af7Sopenharmony_ci            write(predefinedCode % ("uint32_t", "uint32_t"), file=self.outFile)
537e5c31af7Sopenharmony_ci        self.printBaseTypes()
538e5c31af7Sopenharmony_ci        if self.isCTS:
539e5c31af7Sopenharmony_ci            write(encodeBase64CodeCTS, file=self.outFile)
540e5c31af7Sopenharmony_ci        else:
541e5c31af7Sopenharmony_ci            write(encodeBase64Code, file=self.outFile)
542e5c31af7Sopenharmony_ci
543e5c31af7Sopenharmony_ci    def endFile(self):
544e5c31af7Sopenharmony_ci        write(self.printPrototypesAndExtensionDump(), file=self.outFile)
545e5c31af7Sopenharmony_ci        write("}//End of namespace vk_json\n", file=self.outFile) # end of namespace
546e5c31af7Sopenharmony_ci        write(headerGuardBottom, file=self.outFile, end='') # end of _VULKAN_JSON_DATA_HPP
547e5c31af7Sopenharmony_ci        OutputGenerator.endFile(self)
548e5c31af7Sopenharmony_ci
549e5c31af7Sopenharmony_ci    def beginFeature(self, interface, emit):
550e5c31af7Sopenharmony_ci        OutputGenerator.beginFeature(self, interface, emit)
551e5c31af7Sopenharmony_ci        self.sections = {section: [] for section in self.ALL_SECTIONS}
552e5c31af7Sopenharmony_ci        self.feature_not_empty = False
553e5c31af7Sopenharmony_ci
554e5c31af7Sopenharmony_ci    def endFeature(self):
555e5c31af7Sopenharmony_ci        if self.emit:
556e5c31af7Sopenharmony_ci            if self.feature_not_empty:
557e5c31af7Sopenharmony_ci                if self.genOpts.conventions.writeFeature(self.featureExtraProtect, self.genOpts.filename):
558e5c31af7Sopenharmony_ci
559e5c31af7Sopenharmony_ci                    for section in self.TYPE_SECTIONS:
560e5c31af7Sopenharmony_ci                        contents = self.sections[section]
561e5c31af7Sopenharmony_ci                        if contents:
562e5c31af7Sopenharmony_ci                            write('\n'.join(contents), file=self.outFile)
563e5c31af7Sopenharmony_ci
564e5c31af7Sopenharmony_ci        # Finish processing in superclass
565e5c31af7Sopenharmony_ci        OutputGenerator.endFeature(self)
566e5c31af7Sopenharmony_ci
567e5c31af7Sopenharmony_ci    def appendSection(self, section, text):
568e5c31af7Sopenharmony_ci        self.sections[section].append(text)
569e5c31af7Sopenharmony_ci        self.feature_not_empty = True
570e5c31af7Sopenharmony_ci
571e5c31af7Sopenharmony_ci    def genEnumData(self, name, obj):
572e5c31af7Sopenharmony_ci        code = ""
573e5c31af7Sopenharmony_ci        code += "     if (str != \"\") _OUT << \"\\\"\" << str << \"\\\"\" << \" : \";\n"
574e5c31af7Sopenharmony_ci        code += "     if (commaNeeded)\n"
575e5c31af7Sopenharmony_ci        code += "         _OUT << \"\\\"\" <<  %s_map[%sobj] << \"\\\",\" << std::endl;\n" %(name, obj)
576e5c31af7Sopenharmony_ci        code += "     else\n"
577e5c31af7Sopenharmony_ci        code += "         _OUT << \"\\\"\" << %s_map[%sobj] << \"\\\"\" << std::endl;\n" %(name, obj)
578e5c31af7Sopenharmony_ci        return code
579e5c31af7Sopenharmony_ci
580e5c31af7Sopenharmony_ci    def genEnumCode(self, name):
581e5c31af7Sopenharmony_ci        code = ""
582e5c31af7Sopenharmony_ci        code += "static void print_%s(%s obj, const std::string& str, bool commaNeeded=true) {\n" %(name, name)
583e5c31af7Sopenharmony_ci        code += "     PRINT_SPACE\n"
584e5c31af7Sopenharmony_ci        code += self.genEnumData(name, "")
585e5c31af7Sopenharmony_ci        code += "}\n"
586e5c31af7Sopenharmony_ci
587e5c31af7Sopenharmony_ci        code += "static void print_%s(const %s * obj, const std::string& str, bool commaNeeded=true) {\n" %(name, name)
588e5c31af7Sopenharmony_ci        code += "     PRINT_SPACE\n"
589e5c31af7Sopenharmony_ci        code += self.genEnumData(name, "*")
590e5c31af7Sopenharmony_ci        code += "}\n"
591e5c31af7Sopenharmony_ci
592e5c31af7Sopenharmony_ci        return code
593e5c31af7Sopenharmony_ci
594e5c31af7Sopenharmony_ci    def genBasetypeCode(self, str1, str2, name):
595e5c31af7Sopenharmony_ci        code = ""
596e5c31af7Sopenharmony_ci        code += "static void print_" + name + "(" + str1 + name + str2 + " const std::string& str, bool commaNeeded=true) {\n"
597e5c31af7Sopenharmony_ci        code += "     PRINT_SPACE\n"
598e5c31af7Sopenharmony_ci        if name == "VkBool32":
599e5c31af7Sopenharmony_ci            code += "     _OUT << \"\\\"\" << str << \"\\\"\" << \" : \" << \"\\\"\" << ((obj == 0) ? (\"VK_FALSE\") : (\"VK_TRUE\")) << \"\\\"\" << (commaNeeded ? \",\" : \"\") << std::endl;\n"
600e5c31af7Sopenharmony_ci        else:
601e5c31af7Sopenharmony_ci            code += "     _OUT << \"\\\"\" << str << \"\\\"\" << \" : \" << \"\\\"\" << obj << \"\\\"\" << (commaNeeded ? \",\" : \"\") << std::endl;\n"
602e5c31af7Sopenharmony_ci        code += "}\n"
603e5c31af7Sopenharmony_ci        return code
604e5c31af7Sopenharmony_ci
605e5c31af7Sopenharmony_ci    def genHandleCode(self, str1, str2, name):
606e5c31af7Sopenharmony_ci        code = ""
607e5c31af7Sopenharmony_ci        code += "static void print_%s(%s%s%s const std::string& str, bool commaNeeded=true) {\n" %(name, str1, name, str2)
608e5c31af7Sopenharmony_ci        code += "     PRINT_SPACE\n"
609e5c31af7Sopenharmony_ci        code += "     if (commaNeeded)\n"
610e5c31af7Sopenharmony_ci        code += "         _OUT << \"\\\"\" << str << \"\\\"\" << \",\" << std::endl;\n"
611e5c31af7Sopenharmony_ci        code += "     else\n"
612e5c31af7Sopenharmony_ci        code += "         _OUT << \"\\\"\" << str << \"\\\"\" << std::endl;\n"
613e5c31af7Sopenharmony_ci        code += "}\n"
614e5c31af7Sopenharmony_ci        return code
615e5c31af7Sopenharmony_ci
616e5c31af7Sopenharmony_ci    def genBitmaskCode(self, str1, str2, name, mapName):
617e5c31af7Sopenharmony_ci        if mapName is not None:
618e5c31af7Sopenharmony_ci            code = ""
619e5c31af7Sopenharmony_ci            code += "static void print_%s(%s%s%s const std::string& str, bool commaNeeded=true) {\n" %(name, str1, name, str2)
620e5c31af7Sopenharmony_ci            code += "     PRINT_SPACE\n"
621e5c31af7Sopenharmony_ci            code += "     if (str != \"\") _OUT << \"\\\"\" << str << \"\\\"\" << \" : \";\n"
622e5c31af7Sopenharmony_ci            code += "     const int max_bits = 64; // We don't expect the number to be larger.\n"
623e5c31af7Sopenharmony_ci            code += "     std::bitset<max_bits> b(obj);\n"
624e5c31af7Sopenharmony_ci            code += "     _OUT << " + "\"\\\"\"" + ";\n"
625e5c31af7Sopenharmony_ci            code += "     if (obj == 0) _OUT << \"0\";\n"
626e5c31af7Sopenharmony_ci            code += "     for (unsigned int i = 0, bitCount = 0; i < b.size(); i++) {\n"
627e5c31af7Sopenharmony_ci            code += "         if (b[i] == 1) {\n"
628e5c31af7Sopenharmony_ci            code += "             bitCount++;\n"
629e5c31af7Sopenharmony_ci            code += "             if (bitCount < b.count())\n"
630e5c31af7Sopenharmony_ci            code += "                 _OUT << %s_map[1ULL<<i] << \" | \";\n" %(mapName)
631e5c31af7Sopenharmony_ci            code += "             else\n"
632e5c31af7Sopenharmony_ci            code += "                 _OUT << %s_map[1ULL<<i];\n" %(mapName)
633e5c31af7Sopenharmony_ci            code += "         }\n"
634e5c31af7Sopenharmony_ci            code += "     }\n"
635e5c31af7Sopenharmony_ci            code += "     if (commaNeeded)\n"
636e5c31af7Sopenharmony_ci            code += "       _OUT << \"\\\"\" << \",\";\n"
637e5c31af7Sopenharmony_ci            code += "     else\n"
638e5c31af7Sopenharmony_ci            code += "       _OUT << \"\\\"\"<< \"\";\n"
639e5c31af7Sopenharmony_ci            code += "     _OUT << std::endl;\n"
640e5c31af7Sopenharmony_ci            code += "}\n"
641e5c31af7Sopenharmony_ci
642e5c31af7Sopenharmony_ci        else:
643e5c31af7Sopenharmony_ci            code = ""
644e5c31af7Sopenharmony_ci            code += "static void print_%s(%s%s%s const std::string& str, bool commaNeeded=true) {\n" %(name, str1, name, str2)
645e5c31af7Sopenharmony_ci            code += "     PRINT_SPACE\n"
646e5c31af7Sopenharmony_ci            code += "     if (commaNeeded)\n"
647e5c31af7Sopenharmony_ci            code += "         _OUT << \"\\\"\" << str << \"\\\"\" << \" : \" << obj << \",\" << std::endl;\n"
648e5c31af7Sopenharmony_ci            code += "     else\n"
649e5c31af7Sopenharmony_ci            code += "         _OUT << \"\\\"\" << str << \"\\\"\" << \" : \" << obj << std::endl;\n"
650e5c31af7Sopenharmony_ci            code += "}\n"
651e5c31af7Sopenharmony_ci
652e5c31af7Sopenharmony_ci        return code
653e5c31af7Sopenharmony_ci
654e5c31af7Sopenharmony_ci    def genType(self, typeinfo, name, alias):
655e5c31af7Sopenharmony_ci        OutputGenerator.genType(self, typeinfo, name, alias)
656e5c31af7Sopenharmony_ci        typeElem = typeinfo.elem
657e5c31af7Sopenharmony_ci        body = ""
658e5c31af7Sopenharmony_ci
659e5c31af7Sopenharmony_ci        self.vkFeatureLayerList.append(name);
660e5c31af7Sopenharmony_ci
661e5c31af7Sopenharmony_ci        category = typeElem.get('category')
662e5c31af7Sopenharmony_ci        if category == 'funcpointer':
663e5c31af7Sopenharmony_ci            section = 'struct'
664e5c31af7Sopenharmony_ci        else:
665e5c31af7Sopenharmony_ci            section = category
666e5c31af7Sopenharmony_ci
667e5c31af7Sopenharmony_ci        if category in ('struct', 'union'):
668e5c31af7Sopenharmony_ci            self.genStruct(typeinfo, name, alias)
669e5c31af7Sopenharmony_ci        else:
670e5c31af7Sopenharmony_ci            if typeElem.get('category') == 'bitmask':
671e5c31af7Sopenharmony_ci                for elem in typeElem:
672e5c31af7Sopenharmony_ci                    if elem.tag == 'name':
673e5c31af7Sopenharmony_ci                        body += self.genBitmaskCode("", " obj,", elem.text, typeElem.get('requires'))
674e5c31af7Sopenharmony_ci                        body += self.genBitmaskCode("const ", " * obj,", elem.text, typeElem.get('requires'))
675e5c31af7Sopenharmony_ci
676e5c31af7Sopenharmony_ci            elif typeElem.get('category') == 'basetype':
677e5c31af7Sopenharmony_ci                    for elem in typeElem:
678e5c31af7Sopenharmony_ci                        if elem.tag == 'name':
679e5c31af7Sopenharmony_ci                            body += self.genBasetypeCode("", " obj,", elem.text)
680e5c31af7Sopenharmony_ci                            body += self.genBasetypeCode("const ", " * obj,", elem.text)
681e5c31af7Sopenharmony_ci
682e5c31af7Sopenharmony_ci            elif typeElem.get('category') == 'handle':
683e5c31af7Sopenharmony_ci                    for elem in typeElem:
684e5c31af7Sopenharmony_ci                        if elem.tag == 'name':
685e5c31af7Sopenharmony_ci                            body += self.genHandleCode("", " obj,", elem.text)
686e5c31af7Sopenharmony_ci                            body += self.genHandleCode("const ", " * obj,", elem.text)
687e5c31af7Sopenharmony_ci            if body:
688e5c31af7Sopenharmony_ci                self.appendSection(section, body)
689e5c31af7Sopenharmony_ci
690e5c31af7Sopenharmony_ci    def paramIsStruct(self, memberType):
691e5c31af7Sopenharmony_ci        if str(self.getTypeCategory(memberType)) == 'struct':
692e5c31af7Sopenharmony_ci            return 1
693e5c31af7Sopenharmony_ci        return 0
694e5c31af7Sopenharmony_ci
695e5c31af7Sopenharmony_ci    # Helper taken from the validation layers code.
696e5c31af7Sopenharmony_ci    def paramIsPointer(self, param):
697e5c31af7Sopenharmony_ci        ispointer = False
698e5c31af7Sopenharmony_ci        for elem in param:
699e5c31af7Sopenharmony_ci            if elem.tag == 'type' and elem.tail is not None and '*' in elem.tail:
700e5c31af7Sopenharmony_ci                ispointer = True
701e5c31af7Sopenharmony_ci        return ispointer
702e5c31af7Sopenharmony_ci
703e5c31af7Sopenharmony_ci    # Helper taken from the validation layers code.
704e5c31af7Sopenharmony_ci    def paramIsStaticArray(self, param):
705e5c31af7Sopenharmony_ci        isstaticarray = 0
706e5c31af7Sopenharmony_ci        paramname = param.find('name')
707e5c31af7Sopenharmony_ci        if (paramname.tail is not None) and ('[' in paramname.tail) and (']' in paramname.tail):
708e5c31af7Sopenharmony_ci            isstaticarray = paramname.tail.count('[')
709e5c31af7Sopenharmony_ci            if isstaticarray:
710e5c31af7Sopenharmony_ci                arraySize = paramname.tail[1]
711e5c31af7Sopenharmony_ci
712e5c31af7Sopenharmony_ci        if isstaticarray:
713e5c31af7Sopenharmony_ci            return arraySize
714e5c31af7Sopenharmony_ci        else:
715e5c31af7Sopenharmony_ci            return 0
716e5c31af7Sopenharmony_ci
717e5c31af7Sopenharmony_ci    def generateStructMembercode(self, param, str1, str2, str3, str4, memberName, typeName, isCommaNeeded):
718e5c31af7Sopenharmony_ci        length = ""
719e5c31af7Sopenharmony_ci        code = ""
720e5c31af7Sopenharmony_ci        isArr = param.get('len') is not None
721e5c31af7Sopenharmony_ci
722e5c31af7Sopenharmony_ci        if param.get('len') is not None:
723e5c31af7Sopenharmony_ci            length = str2 + param.get('len') + ")"
724e5c31af7Sopenharmony_ci        length = length.replace(')', '')
725e5c31af7Sopenharmony_ci        length = length.replace(',1', '')
726e5c31af7Sopenharmony_ci
727e5c31af7Sopenharmony_ci        code += "     PRINT_SPACE\n"
728e5c31af7Sopenharmony_ci        code += "     _OUT << \"\\\"%s\\\": \" << std::endl;\n" %(memberName)
729e5c31af7Sopenharmony_ci
730e5c31af7Sopenharmony_ci        if self.paramIsPointer(param): code += str4 + memberName + ") {\n"
731e5c31af7Sopenharmony_ci        else:                          code += "     {\n"
732e5c31af7Sopenharmony_ci
733e5c31af7Sopenharmony_ci        # TODO: With some tweak, we can use the genArrayCode() here.
734e5c31af7Sopenharmony_ci        if isArr is True:
735e5c31af7Sopenharmony_ci            code += "         PRINT_SPACE\n"
736e5c31af7Sopenharmony_ci            code += "         _OUT << \"[\" << std::endl;\n"
737e5c31af7Sopenharmony_ci            code += "         for (unsigned int i = 0; i < %s; i++) {\n" %(length)
738e5c31af7Sopenharmony_ci            code += "           if (i+1 == %s)\n" %(length)
739e5c31af7Sopenharmony_ci            code += "               print_%s(%s%s[i], \"%s\", 0);\n" %(typeName, str2, memberName, memberName)
740e5c31af7Sopenharmony_ci            code += "           else\n"
741e5c31af7Sopenharmony_ci            code += "               print_%s(%s%s[i], \"%s\", 1);\n" %(typeName, str2, memberName, memberName)
742e5c31af7Sopenharmony_ci            code += "         }\n"
743e5c31af7Sopenharmony_ci            code += "         PRINT_SPACE\n"
744e5c31af7Sopenharmony_ci            if isCommaNeeded:
745e5c31af7Sopenharmony_ci                code += "         _OUT << \"],\" << std::endl;\n"
746e5c31af7Sopenharmony_ci            else:
747e5c31af7Sopenharmony_ci                code += "         _OUT << \"]\" << std::endl;\n"
748e5c31af7Sopenharmony_ci            code += "    }\n"
749e5c31af7Sopenharmony_ci        else:
750e5c31af7Sopenharmony_ci            if (typeName == "VkAccelerationStructureGeometryKHR"):
751e5c31af7Sopenharmony_ci                code += "           print_%s(*%s%s, \"%s\", %s);\n" %(typeName, str2, memberName, memberName, str(isCommaNeeded))
752e5c31af7Sopenharmony_ci            else:
753e5c31af7Sopenharmony_ci                code += "           print_%s(%s%s, \"%s\", %s);\n" %(typeName, str2, memberName, memberName, str(isCommaNeeded))
754e5c31af7Sopenharmony_ci            code += "     }\n"
755e5c31af7Sopenharmony_ci
756e5c31af7Sopenharmony_ci        if self.paramIsPointer(param):
757e5c31af7Sopenharmony_ci            code += "     else\n"
758e5c31af7Sopenharmony_ci            code += "     {\n"
759e5c31af7Sopenharmony_ci            if isCommaNeeded:
760e5c31af7Sopenharmony_ci                code += "         PRINT_SPACE _OUT << \"\\\"NULL\\\"\"<< \",\"<< std::endl;\n"
761e5c31af7Sopenharmony_ci            else:
762e5c31af7Sopenharmony_ci                code += "         PRINT_SPACE _OUT << \"\\\"NULL\\\"\"<< \"\"<< std::endl;\n"
763e5c31af7Sopenharmony_ci            code += "     }\n"
764e5c31af7Sopenharmony_ci
765e5c31af7Sopenharmony_ci        return code
766e5c31af7Sopenharmony_ci
767e5c31af7Sopenharmony_ci    def genPNextCode(self, str2):
768e5c31af7Sopenharmony_ci        code  = ""
769e5c31af7Sopenharmony_ci        code += "      if (%spNext) {\n" %(str2)
770e5c31af7Sopenharmony_ci        code += "         dumpPNextChain(%spNext);\n" %(str2)
771e5c31af7Sopenharmony_ci        code += "      } else {\n"
772e5c31af7Sopenharmony_ci        code += "         PRINT_SPACE\n"
773e5c31af7Sopenharmony_ci        code += "         _OUT << \"\\\"pNext\\\":\" << \"\\\"NULL\\\"\"<< \",\"<< std::endl;\n"
774e5c31af7Sopenharmony_ci        code += "     }\n"
775e5c31af7Sopenharmony_ci
776e5c31af7Sopenharmony_ci        return code
777e5c31af7Sopenharmony_ci
778e5c31af7Sopenharmony_ci    # Prints out member name followed by empty string.
779e5c31af7Sopenharmony_ci    def genEmptyCode(self, memberName, str2, isCommaNeeded):
780e5c31af7Sopenharmony_ci        code = ""
781e5c31af7Sopenharmony_ci        if not self.isCTS:
782e5c31af7Sopenharmony_ci            code +=  "     /** Note: printing just an empty entry here **/\n"
783e5c31af7Sopenharmony_ci        else:
784e5c31af7Sopenharmony_ci            code +=  "     // CTS : required value\n"
785e5c31af7Sopenharmony_ci        code +=  "     PRINT_SPACE"
786e5c31af7Sopenharmony_ci        if isCommaNeeded:
787e5c31af7Sopenharmony_ci            if self.isCTS and (memberName == "module" or memberName == "layout" or memberName == "renderPass" or memberName == "conversion"):
788e5c31af7Sopenharmony_ci                code +=  "    _OUT << \"\\\"\" << \"%s\" << \"\\\"\" << \" : \" << %s%s.getInternal() << \",\" << std::endl;\n" %(memberName, str2, memberName)
789e5c31af7Sopenharmony_ci            else:
790e5c31af7Sopenharmony_ci                code +=  "    _OUT << \"\\\"\" << \"%s\" << \"\\\"\" << \" : \" << \"\\\"\" << \"\\\",\" << std::endl;\n" %(memberName)
791e5c31af7Sopenharmony_ci        else:
792e5c31af7Sopenharmony_ci            if self.isCTS and (memberName == "module" or memberName == "layout" or memberName == "renderPass" or memberName == "conversion"):
793e5c31af7Sopenharmony_ci                code +=  "    _OUT << \"\\\"\" << \"%s\" << \"\\\"\" << \" : \" << %s%s.getInternal() << std::endl;\n" %(memberName, str2, memberName)
794e5c31af7Sopenharmony_ci            else:
795e5c31af7Sopenharmony_ci                code +=  "    _OUT << \"\\\"\" << \"%s\" << \"\\\"\" << \" : \" << \"\\\"\" << \"\\\"\" << std::endl;\n" %(memberName)
796e5c31af7Sopenharmony_ci        return code
797e5c31af7Sopenharmony_ci
798e5c31af7Sopenharmony_ci    def genArrayCode(self, structName, name, typeName, str2, arraySize, needStrPrint, isArrayType, isCommaNeeded):
799e5c31af7Sopenharmony_ci            comma = "," if isCommaNeeded else ""
800e5c31af7Sopenharmony_ci            code = ""
801e5c31af7Sopenharmony_ci            arraySize = arraySize.replace(')', '')
802e5c31af7Sopenharmony_ci            needsTmp = needStrPrint or (str(self.getTypeCategory(typeName)) == 'handle')
803e5c31af7Sopenharmony_ci
804e5c31af7Sopenharmony_ci            if needStrPrint: printStr = "tmp.str()"
805e5c31af7Sopenharmony_ci            else:            printStr = "\"\""
806e5c31af7Sopenharmony_ci
807e5c31af7Sopenharmony_ci            code += "     PRINT_SPACE\n"
808e5c31af7Sopenharmony_ci            code += "     _OUT << \"\\\"%s\\\":\" << std::endl;\n" %(name)
809e5c31af7Sopenharmony_ci            code += "     PRINT_SPACE\n"
810e5c31af7Sopenharmony_ci            if not isArrayType:
811e5c31af7Sopenharmony_ci                code += "     if (%s%s) {\n" %(str2, name)
812e5c31af7Sopenharmony_ci            code += "       _OUT << \"[\" << std::endl;\n"
813e5c31af7Sopenharmony_ci            code += "       for (unsigned int i = 0; i < %s; i++) {\n" %(arraySize)
814e5c31af7Sopenharmony_ci            if self.isCTS and (structName == "VkPipelineLayoutCreateInfo" or structName == "VkDescriptorSetLayoutBinding"):
815e5c31af7Sopenharmony_ci                code += "           bool isCommaNeeded = (i+1) != %s;\n" %(arraySize)
816e5c31af7Sopenharmony_ci                code += "           if (isCommaNeeded)\n"
817e5c31af7Sopenharmony_ci                code += "           {\n"
818e5c31af7Sopenharmony_ci                code += "               PRINT_SPACE\n"
819e5c31af7Sopenharmony_ci                code += "               _OUT << %s%s[i].getInternal() << \",\" << std::endl;\n" %(str2, name)
820e5c31af7Sopenharmony_ci                code += "           }\n"
821e5c31af7Sopenharmony_ci                code += "           else\n"
822e5c31af7Sopenharmony_ci                code += "           {\n"
823e5c31af7Sopenharmony_ci                code += "               PRINT_SPACE\n"
824e5c31af7Sopenharmony_ci                code += "               _OUT << %s%s[i].getInternal() << std::endl;\n" %(str2, name)
825e5c31af7Sopenharmony_ci                code += "           }\n"
826e5c31af7Sopenharmony_ci            else:
827e5c31af7Sopenharmony_ci                if needsTmp:
828e5c31af7Sopenharmony_ci                    code += "           std:: stringstream tmp;\n"
829e5c31af7Sopenharmony_ci
830e5c31af7Sopenharmony_ci                    # Special case handling for giving unique names for pImmutableSamplers if there are multiple
831e5c31af7Sopenharmony_ci                    # bindings in the same Descriptor set layout.
832e5c31af7Sopenharmony_ci                    if name == "pImmutableSamplers":
833e5c31af7Sopenharmony_ci                        code += "           tmp << \"%s\" << \"_\" << (%sbinding) << \"_\" << i;\n" %(name, str2)
834e5c31af7Sopenharmony_ci                    else:
835e5c31af7Sopenharmony_ci                        code += "           tmp << \"%s\" << \"_\" << i;\n" %(name)
836e5c31af7Sopenharmony_ci
837e5c31af7Sopenharmony_ci                code += "           bool isCommaNeeded = (i+1) != %s;\n" %(arraySize)
838e5c31af7Sopenharmony_ci
839e5c31af7Sopenharmony_ci                if str(self.getTypeCategory(typeName)) == 'handle':
840e5c31af7Sopenharmony_ci                    code += "           print_%s(%s%s[i], tmp.str(), isCommaNeeded);\n" %(typeName, str2, name)
841e5c31af7Sopenharmony_ci                else:
842e5c31af7Sopenharmony_ci                    if self.isCTS and name == "pipelineIdentifier":
843e5c31af7Sopenharmony_ci                        code += "           print_uint32_t((%s)%s%s[i], %s, isCommaNeeded);\n" %(self.baseTypeListMap["uint32_t"], str2, name, printStr)
844e5c31af7Sopenharmony_ci                    else:
845e5c31af7Sopenharmony_ci                        code += "           print_%s(%s%s[i], %s, isCommaNeeded);\n" %(typeName, str2, name, printStr)
846e5c31af7Sopenharmony_ci            code += "       }\n"
847e5c31af7Sopenharmony_ci            code += "       PRINT_SPACE\n"
848e5c31af7Sopenharmony_ci            code += "       _OUT << \"]\" << \"%s\" << std::endl;\n" %(comma)
849e5c31af7Sopenharmony_ci            if not isArrayType == True:
850e5c31af7Sopenharmony_ci                code += "     } else {\n"
851e5c31af7Sopenharmony_ci                code += "       _OUT << \"\\\"NULL\\\"\" << \"%s\" << std::endl;\n" %(comma)
852e5c31af7Sopenharmony_ci                code += "     }\n"
853e5c31af7Sopenharmony_ci            return code
854e5c31af7Sopenharmony_ci
855e5c31af7Sopenharmony_ci    def genStructCode(self, param, str1, str2, str3, str4, structName, isCommaNeeded):
856e5c31af7Sopenharmony_ci        code = ""
857e5c31af7Sopenharmony_ci        memberName = ""
858e5c31af7Sopenharmony_ci        typeName = ""
859e5c31af7Sopenharmony_ci
860e5c31af7Sopenharmony_ci        for elem in param:
861e5c31af7Sopenharmony_ci            if elem.text.find('PFN_') != -1:
862e5c31af7Sopenharmony_ci                return "     /** Note: Ignoring function pointer (%s). **/\n" %(elem.text)
863e5c31af7Sopenharmony_ci
864e5c31af7Sopenharmony_ci            if elem.text == 'pNext':
865e5c31af7Sopenharmony_ci                return self.genPNextCode(str2)
866e5c31af7Sopenharmony_ci
867e5c31af7Sopenharmony_ci            if elem.tag == 'name':
868e5c31af7Sopenharmony_ci                memberName = elem.text
869e5c31af7Sopenharmony_ci
870e5c31af7Sopenharmony_ci            if elem.tag == 'type':
871e5c31af7Sopenharmony_ci                typeName = elem.text
872e5c31af7Sopenharmony_ci
873e5c31af7Sopenharmony_ci            # Some arrays have constant sizes.
874e5c31af7Sopenharmony_ci            if elem.text.find("VK_") != -1:
875e5c31af7Sopenharmony_ci                return self.genArrayCode(structName, memberName, typeName, str2, elem.text, False, True, isCommaNeeded)
876e5c31af7Sopenharmony_ci
877e5c31af7Sopenharmony_ci        if self.paramIsStaticArray(param):
878e5c31af7Sopenharmony_ci            return self.genArrayCode(structName, memberName, typeName, str2, self.paramIsStaticArray(param), False, True, isCommaNeeded)
879e5c31af7Sopenharmony_ci
880e5c31af7Sopenharmony_ci        # If the struct's member is another struct, we need a different way to handle.
881e5c31af7Sopenharmony_ci        elif self.paramIsStruct(typeName) == 1:
882e5c31af7Sopenharmony_ci            code += self.generateStructMembercode(param, str1, str2, str3, str4, memberName, typeName, isCommaNeeded)
883e5c31af7Sopenharmony_ci
884e5c31af7Sopenharmony_ci        # Ignore void* data members
885e5c31af7Sopenharmony_ci        elif self.paramIsPointer(param) and typeName == 'void':
886e5c31af7Sopenharmony_ci            if structName == "VkSpecializationInfo":
887e5c31af7Sopenharmony_ci                    return "     print_void_data(%s%s, int(%sdataSize), \"%s\", 0);\n" %(str2, memberName, str2, memberName)
888e5c31af7Sopenharmony_ci            if self.isCTS:
889e5c31af7Sopenharmony_ci                if structName == "VkPipelineCacheCreateInfo":
890e5c31af7Sopenharmony_ci                    return "     print_void_data(%s%s, int(%sinitialDataSize), \"%s\", 0);\n" %(str2, memberName, str2, memberName)
891e5c31af7Sopenharmony_ci            return "     /** Note: Ignoring void* data. **/\n"
892e5c31af7Sopenharmony_ci
893e5c31af7Sopenharmony_ci        # For pointers where we have the 'len' field, dump them as arrays.
894e5c31af7Sopenharmony_ci        elif self.paramIsPointer(param) and param.get('len') is not None and param.get('len').find('null-terminated') == -1 and param.get('len').find('latexmath') == -1:
895e5c31af7Sopenharmony_ci            if memberName == "versionData":
896e5c31af7Sopenharmony_ci                return self.genArrayCode(structName, memberName, typeName, str2, param.get('len')+")", False, False, isCommaNeeded)
897e5c31af7Sopenharmony_ci            else:
898e5c31af7Sopenharmony_ci                return self.genArrayCode(structName, memberName, typeName, str2, str2+param.get('len')+")", False, False, isCommaNeeded)
899e5c31af7Sopenharmony_ci
900e5c31af7Sopenharmony_ci        # Special handling for VkPipelineMultisampleStateCreateInfo::pSampleMask
901e5c31af7Sopenharmony_ci        elif typeName in "VkSampleMask":
902e5c31af7Sopenharmony_ci            code += "     %s sampleMaskSize = ((%srasterizationSamples + 31) / 32);\n" % (self.baseTypeListMap["uint32_t"], str2)
903e5c31af7Sopenharmony_ci            code += self.genArrayCode(structName, memberName, "uint32_t", str2, "sampleMaskSize", False, False, isCommaNeeded)
904e5c31af7Sopenharmony_ci            return code
905e5c31af7Sopenharmony_ci
906e5c31af7Sopenharmony_ci        # If a struct member is just a handle.
907e5c31af7Sopenharmony_ci        elif str(self.getTypeCategory(typeName)) == 'handle':
908e5c31af7Sopenharmony_ci            return self.genEmptyCode(memberName, str2, isCommaNeeded)
909e5c31af7Sopenharmony_ci
910e5c31af7Sopenharmony_ci        else:
911e5c31af7Sopenharmony_ci            code += "     print_%s(%s%s, \"%s\", %s);\n" %(typeName, str2, memberName, memberName, str(isCommaNeeded))
912e5c31af7Sopenharmony_ci
913e5c31af7Sopenharmony_ci        return code
914e5c31af7Sopenharmony_ci
915e5c31af7Sopenharmony_ci    def genStruct(self, typeinfo, typeName, alias):
916e5c31af7Sopenharmony_ci        OutputGenerator.genStruct(self, typeinfo, typeName, alias)
917e5c31af7Sopenharmony_ci        body = ""
918e5c31af7Sopenharmony_ci        typeElem = typeinfo.elem
919e5c31af7Sopenharmony_ci
920e5c31af7Sopenharmony_ci        if alias:
921e5c31af7Sopenharmony_ci            body = 'typedef ' + alias + ' ' + typeName + ';\n'
922e5c31af7Sopenharmony_ci        else:
923e5c31af7Sopenharmony_ci            genStr1 = [""   , "const "]
924e5c31af7Sopenharmony_ci            genStr2 = ["obj.", "obj->" ]
925e5c31af7Sopenharmony_ci            genStr3 = [" obj, const std::string& s, bool commaNeeded=true) {" , " * obj, const std::string& s, bool commaNeeded=true) {"]
926e5c31af7Sopenharmony_ci            genStr4 = ["     if (obj.", "     if (obj->"]
927e5c31af7Sopenharmony_ci
928e5c31af7Sopenharmony_ci            for index in range(len(genStr1)):
929e5c31af7Sopenharmony_ci                body += "static void print_%s(%s%s%s\n" %(typeName, genStr1[index], typeName, genStr3[index])
930e5c31af7Sopenharmony_ci                body += "     PRINT_SPACE\n"
931e5c31af7Sopenharmony_ci                body += "     _OUT << \"{\" << std::endl;\n"
932e5c31af7Sopenharmony_ci                body += "     INDENT(4);\n"
933e5c31af7Sopenharmony_ci                body += "\n"
934e5c31af7Sopenharmony_ci                count = 0
935e5c31af7Sopenharmony_ci                numMembers = len(typeElem.findall('.//member'))
936e5c31af7Sopenharmony_ci
937e5c31af7Sopenharmony_ci                isCommaNeeded = 1
938e5c31af7Sopenharmony_ci                for member in typeElem.findall('.//member'):
939e5c31af7Sopenharmony_ci                    count = count + 1
940e5c31af7Sopenharmony_ci                    if count == numMembers:
941e5c31af7Sopenharmony_ci                        isCommaNeeded = 0
942e5c31af7Sopenharmony_ci
943e5c31af7Sopenharmony_ci                    body += self.genStructCode(member, genStr1[index], genStr2[index], genStr3[index], genStr4[index], typeName, isCommaNeeded)
944e5c31af7Sopenharmony_ci                    body += "\n"
945e5c31af7Sopenharmony_ci
946e5c31af7Sopenharmony_ci                body += "     INDENT(-4);\n"
947e5c31af7Sopenharmony_ci                body += "     PRINT_SPACE\n"
948e5c31af7Sopenharmony_ci                body += "     if (commaNeeded)\n"
949e5c31af7Sopenharmony_ci                body += "         _OUT << \"},\" << std::endl;\n"
950e5c31af7Sopenharmony_ci                body += "     else\n"
951e5c31af7Sopenharmony_ci                body += "         _OUT << \"}\" << std::endl;\n"
952e5c31af7Sopenharmony_ci                body += "}\n"
953e5c31af7Sopenharmony_ci
954e5c31af7Sopenharmony_ci        self.appendSection('struct', body)
955e5c31af7Sopenharmony_ci
956e5c31af7Sopenharmony_ci    def genGroup(self, groupinfo, groupName, alias=None):
957e5c31af7Sopenharmony_ci        OutputGenerator.genGroup(self, groupinfo, groupName, alias)
958e5c31af7Sopenharmony_ci        groupElem = groupinfo.elem
959e5c31af7Sopenharmony_ci        body = ""
960e5c31af7Sopenharmony_ci        section = 'enum'
961e5c31af7Sopenharmony_ci
962e5c31af7Sopenharmony_ci        body += "static std::map<%s, std::string> %s_map = {\n" %(self.baseTypeListMap["uint64_t"], groupName)
963e5c31af7Sopenharmony_ci        enums = groupElem.findall('enum')
964e5c31af7Sopenharmony_ci
965e5c31af7Sopenharmony_ci        for enum in enums:
966e5c31af7Sopenharmony_ci            if enum.get('value'):
967e5c31af7Sopenharmony_ci                body += "    std::make_pair(%s, \"%s\"),\n" %(enum.get('value'), enum.get('name'))
968e5c31af7Sopenharmony_ci
969e5c31af7Sopenharmony_ci            elif enum.get('bitpos'):
970e5c31af7Sopenharmony_ci                body += "    std::make_pair(1ULL << %s, \"%s\"),\n" %(enum.get('bitpos'), enum.get('name'))
971e5c31af7Sopenharmony_ci
972e5c31af7Sopenharmony_ci            #TODO: Some enums have no offset. How to handle those?
973e5c31af7Sopenharmony_ci            elif enum.get('extends') and enum.get("extnumber") and enum.get("offset"):
974e5c31af7Sopenharmony_ci                extNumber = int(enum.get("extnumber"))
975e5c31af7Sopenharmony_ci                offset = int(enum.get("offset"))
976e5c31af7Sopenharmony_ci                enumVal = self.extBase + (extNumber - 1) * self.extBlockSize + offset
977e5c31af7Sopenharmony_ci                body += "    std::make_pair(%s, \"%s\"),\n" %(str(enumVal), enum.get('name'))
978e5c31af7Sopenharmony_ci
979e5c31af7Sopenharmony_ci        body += "};\n"
980e5c31af7Sopenharmony_ci        body += self.genEnumCode(groupName)
981e5c31af7Sopenharmony_ci
982e5c31af7Sopenharmony_ci        self.appendSection(section, body)
983