# Copyright (c) 2018 The Android Open Source Project
# Copyright (c) 2018 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from copy import copy

from .common.codegen import CodeGen, VulkanAPIWrapper
from .common.vulkantypes import \
        VulkanAPI, makeVulkanTypeSimple, iterateVulkanType, VulkanTypeIterator, Atom, FuncExpr, FuncExprVal, FuncLambda

from .wrapperdefs import VulkanWrapperGenerator
from .wrapperdefs import VULKAN_STREAM_VAR_NAME
from .wrapperdefs import ROOT_TYPE_VAR_NAME, ROOT_TYPE_PARAM
from .wrapperdefs import STREAM_RET_TYPE
from .wrapperdefs import MARSHAL_INPUT_VAR_NAME
from .wrapperdefs import UNMARSHAL_INPUT_VAR_NAME
from .wrapperdefs import PARAMETERS_MARSHALING
from .wrapperdefs import PARAMETERS_MARSHALING_GUEST
from .wrapperdefs import STYPE_OVERRIDE
from .wrapperdefs import STRUCT_EXTENSION_PARAM, STRUCT_EXTENSION_PARAM_FOR_WRITE, EXTENSION_SIZE_WITH_STREAM_FEATURES_API_NAME
from .wrapperdefs import API_PREFIX_RESERVEDMARSHAL
from .wrapperdefs import API_PREFIX_RESERVEDUNMARSHAL

from .marshalingdefs import CUSTOM_MARSHAL_TYPES
class VulkanReservedMarshalingCodegen(VulkanTypeIterator):
    def __init__(self,
                 cgen,
                 streamVarName,
                 rootTypeVarName,
                 inputVarName,
                 ptrVarName,
                 marshalPrefix,
                 handlemapPrefix,
                 direction = "write",
                 forApiOutput = False,
                 dynAlloc = False,
                 mapHandles = True,
                 handleMapOverwrites = False,
                 doFiltering = True,
                 stackVar=None,
                 stackArrSize=None):
        self.cgen = cgen
        self.direction = direction
        self.processSimple = "write" if self.direction == "write" else "read"
        self.forApiOutput = forApiOutput

        self.checked = False

        self.streamVarName = streamVarName
        self.rootTypeVarName = rootTypeVarName
        self.inputVarName = inputVarName
        self.ptrVar = ptrVarName
        self.marshalPrefix = marshalPrefix
        self.handlemapPrefix = handlemapPrefix

        self.exprAccessor = lambda t: self.cgen.generalAccess(t, parentVarName = self.inputVarName, asPtr = True)
        self.exprValueAccessor = lambda t: self.cgen.generalAccess(t, parentVarName = self.inputVarName, asPtr = False)
        self.exprPrimitiveValueAccessor = lambda t: self.cgen.generalAccess(t, parentVarName = self.inputVarName, asPtr = False)
        self.lenAccessor = lambda t: self.cgen.generalLengthAccess(t, parentVarName = self.inputVarName)
        self.lenAccessorGuard = lambda t: self.cgen.generalLengthAccessGuard(
            t, parentVarName=self.inputVarName)
        self.filterVarAccessor = lambda t: self.cgen.filterVarAccess(t, parentVarName = self.inputVarName)

        self.dynAlloc = dynAlloc
        self.mapHandles = mapHandles
        self.handleMapOverwrites = handleMapOverwrites
        self.doFiltering = doFiltering

        self.stackVar = stackVar
        self.stackArrSize = stackArrSize

    def getTypeForStreaming(self, vulkanType):
        res = copy(vulkanType)

        if not vulkanType.accessibleAsPointer():
            res = res.getForAddressAccess()

        if vulkanType.staticArrExpr:
            res = res.getForAddressAccess()

        if self.direction == "write":
            return res
        else:
            return res.getForNonConstAccess()

    def makeCastExpr(self, vulkanType):
        return "(%s)" % (
            self.cgen.makeCTypeDecl(vulkanType, useParamName=False))

    def genPtrIncr(self, sizeExpr):
        self.cgen.stmt("*%s += %s" % (self.ptrVar, sizeExpr))

    def genMemcpyAndIncr(self, varname, cast, toStreamExpr, sizeExpr, toBe = False, actualSize = 4):
        if self.direction == "write":
            self.cgen.stmt("memcpy(*%s, %s%s, %s)" % (varname, cast, toStreamExpr, sizeExpr))
        else:
            self.cgen.stmt("memcpy(%s%s, *%s, %s)" % (cast, toStreamExpr, varname, sizeExpr))

        if toBe:
            streamPrefix = "to"
            if "read" == self.direction:
                streamPrefix = "from"

            streamMethod = streamPrefix

            if 1 == actualSize:
                streamMethod += "Byte"
            elif 2 == actualSize:
                streamMethod += "Be16"
            elif 4 == actualSize:
                streamMethod += "Be32"
            elif 8 == actualSize:
                streamMethod += "Be64"
            else:
                pass

            if self.direction == "write":
                self.cgen.stmt("android::base::Stream::%s((uint8_t*)*%s)" % (streamMethod, varname))
            else:
                self.cgen.stmt("android::base::Stream::%s((uint8_t*)%s)" % (streamMethod, toStreamExpr))

        self.genPtrIncr(sizeExpr)

    def genStreamCall(self, vulkanType, toStreamExpr, sizeExpr):
        varname = self.ptrVar
        cast = self.makeCastExpr(self.getTypeForStreaming(vulkanType))
        self.genMemcpyAndIncr(varname, cast, toStreamExpr, sizeExpr)
    
    def genPrimitiveStreamCall(self, vulkanType, access):
        varname = self.ptrVar
        self.cgen.memcpyPrimitive(
            self.typeInfo,
            "(*" + varname + ")",
            access,
            vulkanType,
            direction=self.direction)
        self.genPtrIncr(str(self.cgen.countPrimitive(
            self.typeInfo,
            vulkanType)))

    def genHandleMappingCall(self, vulkanType, access, lenAccess, lenAccessGuard):

        if lenAccess is None:
            lenAccess = "1"
            handle64Bytes = "8"
        else:
            handle64Bytes = "%s * 8" % lenAccess

        handle64Var = self.cgen.var()
        if lenAccess != "1":
            self.cgen.beginIf(lenAccess)
            self.cgen.stmt("uint8_t* %s_ptr = (uint8_t*)(*%s)" % (handle64Var, self.ptrVar))
            handle64VarAccess = handle64Var
            handle64VarType = \
                makeVulkanTypeSimple(False, "uint64_t", 1, paramName=handle64Var)
        else:
            self.cgen.stmt("uint64_t %s" % handle64Var)
            handle64VarAccess = "&%s" % handle64Var
            handle64VarType = \
                makeVulkanTypeSimple(False, "uint64_t", 0, paramName=handle64Var)

        if "" == self.handlemapPrefix:
            mapFunc = ("(%s)" % vulkanType.typeName)
            mapFunc64 = ("(%s)" % "uint64_t")
        else:
            mapFunc = self.handlemapPrefix + vulkanType.typeName
            mapFunc64 = mapFunc

        if self.direction == "write":
            if self.handleMapOverwrites:
                self.cgen.stmt(
                    "static_assert(8 == sizeof(%s), \"handle map overwrite requres %s to be 8 bytes long\")" % \
                            (vulkanType.typeName, vulkanType.typeName))
                if "1" == lenAccess:
                    self.cgen.stmt("*%s = (%s)%s(*%s)" % (access, vulkanType.typeName, mapFunc, access))
                    self.genStreamCall(vulkanType, access, "8 * %s" % lenAccess)
                else:
                    if lenAccessGuard is not None:
                        self.cgen.beginIf(lenAccessGuard)
                    self.cgen.beginFor("uint32_t k = 0", "k < %s" % lenAccess, "++k")
                    self.cgen.stmt("%s[k] = (%s)%s(%s[k])" % (access, vulkanType.typeName, mapFunc, access))
                    self.cgen.endFor()
                    if lenAccessGuard is not None:
                        self.cgen.endIf()
                    self.genPtrIncr("8 * %s" % lenAccess)
            else:
                if "1" == lenAccess:
                    self.cgen.stmt("*%s = %s((*%s))" % (handle64VarAccess, mapFunc64, access))
                    self.genStreamCall(handle64VarType, handle64VarAccess, handle64Bytes)
                else:
                    if lenAccessGuard is not None:
                        self.cgen.beginIf(lenAccessGuard)
                    self.cgen.beginFor("uint32_t k = 0", "k < %s" % lenAccess, "++k")
                    self.cgen.stmt("uint64_t tmpval = %s(%s[k])" % (mapFunc64, access))
                    self.cgen.stmt("memcpy(%s_ptr + k * 8, &tmpval, sizeof(uint64_t))" % (handle64Var))
                    self.cgen.endFor()
                    if lenAccessGuard is not None:
                        self.cgen.endIf()
                    self.genPtrIncr("8 * %s" % lenAccess)
        else:
            if "1" == lenAccess:
                self.genStreamCall(handle64VarType, handle64VarAccess, handle64Bytes)
                self.cgen.stmt("*%s%s = (%s)%s((%s)(*%s))" % (
                    self.makeCastExpr(vulkanType.getForNonConstAccess()), access,
                    vulkanType.typeName,mapFunc, vulkanType.typeName, handle64VarAccess))
            else:
                self.genPtrIncr("8 * %s" % lenAccess)
                if lenAccessGuard is not None:
                    self.cgen.beginIf(lenAccessGuard)
                self.cgen.beginFor("uint32_t k = 0", "k < %s" % lenAccess, "++k")
                self.cgen.stmt("uint64_t tmpval; memcpy(&tmpval, %s_ptr + k * 8, sizeof(uint64_t))" % handle64Var)
                self.cgen.stmt("*((%s%s) + k) = (%s)%s((%s)tmpval)" % (
                    self.makeCastExpr(vulkanType.getForNonConstAccess()), access,
                    vulkanType.typeName, mapFunc, vulkanType.typeName))
                if lenAccessGuard is not None:
                    self.cgen.endIf()
                self.cgen.endFor()

        if lenAccess != "1":
            self.cgen.endIf()

    def doAllocSpace(self, vulkanType):
        if self.dynAlloc and self.direction == "read":
            access = self.exprAccessor(vulkanType)
            lenAccess = self.lenAccessor(vulkanType)
            sizeof = self.cgen.sizeofExpr( \
                         vulkanType.getForValueAccess())
            if lenAccess:
                bytesExpr = "%s * %s" % (lenAccess, sizeof)
            else:
                bytesExpr = sizeof
                lenAccess = "1"

            if self.stackVar:
                if self.stackArrSize != lenAccess:
                    self.cgen.beginIf("%s <= %s" % (lenAccess, self.stackArrSize))

                self.cgen.stmt( \
                        "%s = %s%s" % (access, self.makeCastExpr(vulkanType.getForNonConstAccess()), self.stackVar))

                if self.stackArrSize != lenAccess:
                    self.cgen.endIf()
                    self.cgen.beginElse()

                if self.stackArrSize != lenAccess:
                    self.cgen.stmt( \
                            "%s->alloc((void**)&%s, %s)" %
                            (self.streamVarName,
                                access, bytesExpr))

                if self.stackArrSize != lenAccess:
                    self.cgen.endIf()
            else:
                self.cgen.stmt( \
                        "%s->alloc((void**)&%s, %s)" %
                        (self.streamVarName,
                            access, bytesExpr))

    def getOptionalStringFeatureExpr(self, vulkanType):
        if vulkanType.optionalStr is not None:
            if vulkanType.optionalStr.startswith("streamFeature:"):
                splitted = vulkanType.optionalStr.split(":")
                featureExpr = "%s->getFeatureBits() & %s" % (self.streamVarName, splitted[1])
                return featureExpr
        return None

    def onCheck(self, vulkanType):

        if self.forApiOutput:
            return

        featureExpr = self.getOptionalStringFeatureExpr(vulkanType);

        self.checked = True

        access = self.exprAccessor(vulkanType)

        needConsistencyCheck = False

        self.cgen.line("// WARNING PTR CHECK")
        if (self.dynAlloc and self.direction == "read") or self.direction == "write":
            checkAccess = self.exprAccessor(vulkanType)
            addrExpr = "&" + checkAccess
            sizeExpr = self.cgen.sizeofExpr(vulkanType)
        else:
            checkName = "check_%s" % vulkanType.paramName
            self.cgen.stmt("%s %s" % (
                self.cgen.makeCTypeDecl(vulkanType, useParamName = False), checkName))
            checkAccess = checkName
            addrExpr = "&" + checkAccess
            sizeExpr = self.cgen.sizeofExpr(vulkanType)
            needConsistencyCheck = True

        if featureExpr is not None:
            self.cgen.beginIf(featureExpr)

        self.genPrimitiveStreamCall(
            vulkanType,
            checkAccess)

        if featureExpr is not None:
            self.cgen.endIf()

        if featureExpr is not None:
            self.cgen.beginIf("(!(%s) || %s)" % (featureExpr, access))
        else:
            self.cgen.beginIf(access)

        if needConsistencyCheck and featureExpr is None:
            self.cgen.beginIf("!(%s)" % checkName)
            self.cgen.stmt(
                "fprintf(stderr, \"fatal: %s inconsistent between guest and host\\n\")" % (access))
            self.cgen.endIf()

    def onCheckWithNullOptionalStringFeature(self, vulkanType):
        self.cgen.beginIf("%s->getFeatureBits() & VULKAN_STREAM_FEATURE_NULL_OPTIONAL_STRINGS_BIT" % self.streamVarName)
        self.onCheck(vulkanType)

    def endCheckWithNullOptionalStringFeature(self, vulkanType):
        self.endCheck(vulkanType)
        self.cgen.endIf()
        self.cgen.beginElse()

    def finalCheckWithNullOptionalStringFeature(self, vulkanType):
        self.cgen.endElse()

    def endCheck(self, vulkanType):

        if self.checked:
            self.cgen.endIf()
            self.checked = False

    def genFilterFunc(self, filterfunc, env):

        def loop(expr, lambdaEnv={}):
            def do_func(expr):
                fnamestr = expr.name.name
                if "not" == fnamestr:
                    return "!(%s)" % (loop(expr.args[0], lambdaEnv))
                if "eq" == fnamestr:
                    return "(%s == %s)" % (loop(expr.args[0], lambdaEnv), loop(expr.args[1], lambdaEnv))
                if "and" == fnamestr:
                    return "(%s && %s)" % (loop(expr.args[0], lambdaEnv), loop(expr.args[1], lambdaEnv))
                if "or" == fnamestr:
                    return "(%s || %s)" % (loop(expr.args[0], lambdaEnv), loop(expr.args[1], lambdaEnv))
                if "getfield" == fnamestr:
                    ptrlevels = get_ptrlevels(expr.args[0].val.name)
                    if ptrlevels == 0:
                        return "%s.%s" % (loop(expr.args[0], lambdaEnv), expr.args[1].val)
                    else:
                        return "(%s(%s)).%s" % ("*" * ptrlevels, loop(expr.args[0], lambdaEnv), expr.args[1].val)

                if "if" == fnamestr:
                    return "((%s) ? (%s) : (%s))" % (loop(expr.args[0], lambdaEnv), loop(expr.args[1], lambdaEnv), loop(expr.args[2], lambdaEnv))

                return "%s(%s)" % (fnamestr, ", ".join(map(lambda e: loop(e, lambdaEnv), expr.args)))

            def do_expratom(atomname, lambdaEnv= {}):
                if lambdaEnv.get(atomname, None) is not None:
                    return atomname

                enventry = env.get(atomname, None)
                if None != enventry:
                    return self.getEnvAccessExpr(atomname)
                return atomname

            def get_ptrlevels(atomname, lambdaEnv= {}):
                if lambdaEnv.get(atomname, None) is not None:
                    return 0

                enventry = env.get(atomname, None)
                if None != enventry:
                    return self.getPointerIndirectionLevels(atomname)

                return 0

            def do_exprval(expr, lambdaEnv= {}):
                expratom = expr.val

                if Atom == type(expratom):
                    return do_expratom(expratom.name, lambdaEnv)

                return "%s" % expratom

            def do_lambda(expr, lambdaEnv= {}):
                params = expr.vs
                body = expr.body
                newEnv = {}

                for (k, v) in lambdaEnv.items():
                    newEnv[k] = v

                for p in params:
                    newEnv[p.name] = p.typ

                return "[](%s) { return %s; }" % (", ".join(list(map(lambda p: "%s %s" % (p.typ, p.name), params))), loop(body, lambdaEnv=newEnv))

            if FuncExpr == type(expr):
                return do_func(expr)
            if FuncLambda == type(expr):
                return do_lambda(expr)
            elif FuncExprVal == type(expr):
                return do_exprval(expr)

        return loop(filterfunc)

    def beginFilterGuard(self, vulkanType):
        if vulkanType.filterVar == None:
            return

        if self.doFiltering == False:
            return

        filterVarAccess = self.getEnvAccessExpr(vulkanType.filterVar)

        filterValsExpr = None
        filterFuncExpr = None
        filterExpr = None

        filterFeature = "%s->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT" % self.streamVarName

        if None != vulkanType.filterVals:
            filterValsExpr = " || ".join(map(lambda filterval: "(%s == %s)" % (filterval, filterVarAccess), vulkanType.filterVals))

        if None != vulkanType.filterFunc:
            filterFuncExpr = self.genFilterFunc(vulkanType.filterFunc, self.currentStructInfo.environment)

        if None != filterValsExpr and None != filterFuncExpr:
            filterExpr = "%s || %s" % (filterValsExpr, filterFuncExpr)
        elif None == filterValsExpr and None == filterFuncExpr:
            # Assume is bool
            self.cgen.beginIf(filterVarAccess)
        elif None != filterValsExpr:
            self.cgen.beginIf("(!(%s) || (%s))" % (filterFeature, filterValsExpr))
        elif None != filterFuncExpr:
            self.cgen.beginIf("(!(%s) || (%s))" % (filterFeature, filterFuncExpr))

    def endFilterGuard(self, vulkanType, cleanupExpr=None):
        if vulkanType.filterVar == None:
            return

        if self.doFiltering == False:
            return

        if cleanupExpr == None:
            self.cgen.endIf()
        else:
            self.cgen.endIf()
            self.cgen.beginElse()
            self.cgen.stmt(cleanupExpr)
            self.cgen.endElse()

    def getEnvAccessExpr(self, varName):
        parentEnvEntry = self.currentStructInfo.environment.get(varName, None)

        if parentEnvEntry != None:
            isParentMember = parentEnvEntry["structmember"]

            if isParentMember:
                envAccess = self.exprValueAccessor(list(filter(lambda member: member.paramName == varName, self.currentStructInfo.members))[0])
            else:
                envAccess = varName
            return envAccess

        return None

    def getPointerIndirectionLevels(self, varName):
        parentEnvEntry = self.currentStructInfo.environment.get(varName, None)

        if parentEnvEntry != None:
            isParentMember = parentEnvEntry["structmember"]

            if isParentMember:
                return list(filter(lambda member: member.paramName == varName, self.currentStructInfo.members))[0].pointerIndirectionLevels
            else:
                return 0
            return 0

        return 0


    def onCompoundType(self, vulkanType):

        access = self.exprAccessor(vulkanType)
        lenAccess = self.lenAccessor(vulkanType)

        self.beginFilterGuard(vulkanType)

        if vulkanType.pointerIndirectionLevels > 0:
            self.doAllocSpace(vulkanType)

        if lenAccess is not None:
            loopVar = "i"
            access = "%s + %s" % (access, loopVar)
            forInit = "uint32_t %s = 0" % loopVar
            forCond = "%s < (uint32_t)%s" % (loopVar, lenAccess)
            forIncr = "++%s" % loopVar
            self.cgen.beginFor(forInit, forCond, forIncr)

        accessWithCast = "%s(%s)" % (self.makeCastExpr(
            self.getTypeForStreaming(vulkanType)), access)

        callParams = [self.streamVarName, self.rootTypeVarName, accessWithCast, self.ptrVar]

        for (bindName, localName) in vulkanType.binds.items():
            callParams.append(self.getEnvAccessExpr(localName))

        self.cgen.funcCall(None, self.marshalPrefix + vulkanType.typeName,
                           callParams)

        if lenAccess is not None:
            self.cgen.endFor()

        if self.direction == "read":
            self.endFilterGuard(vulkanType, "%s = 0" % self.exprAccessor(vulkanType))
        else:
            self.endFilterGuard(vulkanType)

    def onString(self, vulkanType):
        access = self.exprAccessor(vulkanType)

        if self.direction == "write":
            self.cgen.beginBlock()
            self.cgen.stmt("uint32_t l = %s ? strlen(%s): 0" % (access, access))
            self.genMemcpyAndIncr(self.ptrVar, "(uint32_t*)" ,"&l", "sizeof(uint32_t)", toBe = True, actualSize = 4)
            self.genMemcpyAndIncr(self.ptrVar, "(char*)", access, "l")
            self.cgen.endBlock()
        else:
            castExpr = \
                self.makeCastExpr( \
                    self.getTypeForStreaming( \
                        vulkanType.getForAddressAccess()))
            self.cgen.stmt( \
                "%s->loadStringInPlaceWithStreamPtr(%s&%s, %s)" % (self.streamVarName, castExpr, access, self.ptrVar))

    def onStringArray(self, vulkanType):
        access = self.exprAccessor(vulkanType)
        lenAccess = self.lenAccessor(vulkanType)
        lenAccessGuard = self.lenAccessorGuard(vulkanType)

        if self.direction == "write":
            self.cgen.beginBlock()

            self.cgen.stmt("uint32_t c = 0")
            if lenAccessGuard is not None:
                self.cgen.beginIf(lenAccessGuard)
            self.cgen.stmt("c = %s" % (lenAccess))
            if lenAccessGuard is not None:
                self.cgen.endIf()
            self.genMemcpyAndIncr(self.ptrVar, "(uint32_t*)" ,"&c", "sizeof(uint32_t)", toBe = True, actualSize = 4)

            self.cgen.beginFor("uint32_t i = 0", "i < c", "++i")
            self.cgen.stmt("uint32_t l = %s ? strlen(%s[i]): 0" % (access, access))
            self.genMemcpyAndIncr(self.ptrVar, "(uint32_t*)" ,"&l", "sizeof(uint32_t)", toBe = True, actualSize = 4)
            self.cgen.beginIf("l")
            self.genMemcpyAndIncr(self.ptrVar, "(char*)", "(%s[i])" % access, "l")
            self.cgen.endIf()
            self.cgen.endFor()

            self.cgen.endBlock()
        else:
            castExpr = \
                self.makeCastExpr( \
                    self.getTypeForStreaming( \
                        vulkanType.getForAddressAccess()))

            self.cgen.stmt("%s->loadStringArrayInPlaceWithStreamPtr(%s&%s, %s)" % (self.streamVarName, castExpr, access, self.ptrVar))

    def onStaticArr(self, vulkanType):
        access = self.exprValueAccessor(vulkanType)
        lenAccess = self.lenAccessor(vulkanType)
        finalLenExpr = "%s * %s" % (lenAccess, self.cgen.sizeofExpr(vulkanType))
        self.genStreamCall(vulkanType, access, finalLenExpr)

    # Old version VkEncoder may have some sType values conflict with VkDecoder
    # of new versions. For host decoder, it should not carry the incorrect old
    # sType values to the |forUnmarshaling| struct. Instead it should overwrite
    # the sType value.
    def overwriteSType(self, vulkanType):
        if self.direction == "read":
            sTypeParam = copy(vulkanType)
            sTypeParam.paramName = "sType"
            sTypeAccess = self.exprAccessor(sTypeParam)

            typeName = vulkanType.parent.typeName
            if typeName in STYPE_OVERRIDE:
                self.cgen.stmt("%s = %s" %
                               (sTypeAccess, STYPE_OVERRIDE[typeName]))

    def onStructExtension(self, vulkanType):
        self.overwriteSType(vulkanType)

        sTypeParam = copy(vulkanType)
        sTypeParam.paramName = "sType"

        access = self.exprAccessor(vulkanType)
        sizeVar = "%s_size" % vulkanType.paramName

        if self.direction == "read":
            castedAccessExpr = "(%s)(%s)" % ("void*", access)
        else:
            castedAccessExpr = access

        sTypeAccess = self.exprAccessor(sTypeParam)
        self.cgen.beginIf("%s == VK_STRUCTURE_TYPE_MAX_ENUM" % self.rootTypeVarName)
        self.cgen.stmt("%s = %s" % (self.rootTypeVarName, sTypeAccess))
        self.cgen.endIf()

        if self.direction == "read" and self.dynAlloc:
            self.cgen.stmt("uint32_t %s" % sizeVar)

            self.genMemcpyAndIncr(self.ptrVar, "(uint32_t*)", "&" + sizeVar, "sizeof(uint32_t)", toBe = True, actualSize = 4)

            self.cgen.stmt("%s = nullptr" % access)
            self.cgen.beginIf(sizeVar)
            self.cgen.stmt( \
                    "%s->alloc((void**)&%s, sizeof(VkStructureType))" %
                    (self.streamVarName, access))

            self.genStreamCall(vulkanType, access, "sizeof(VkStructureType)")
            self.cgen.stmt("VkStructureType extType = *(VkStructureType*)(%s)" % access)
            self.cgen.stmt( \
                    "%s->alloc((void**)&%s, %s(%s->getFeatureBits(), %s, %s))" %
                    (self.streamVarName, access, EXTENSION_SIZE_WITH_STREAM_FEATURES_API_NAME, self.streamVarName, self.rootTypeVarName, access))
            self.cgen.stmt("*(VkStructureType*)%s = extType" % access)

            self.cgen.funcCall(None, self.marshalPrefix + "extension_struct",
                [self.streamVarName, self.rootTypeVarName, castedAccessExpr, self.ptrVar])
            self.cgen.endIf()
        else:

            self.cgen.funcCall(None, self.marshalPrefix + "extension_struct",
                [self.streamVarName, self.rootTypeVarName, castedAccessExpr, self.ptrVar])

    def onPointer(self, vulkanType):
        access = self.exprAccessor(vulkanType)

        lenAccess = self.lenAccessor(vulkanType)
        lenAccessGuard = self.lenAccessorGuard(vulkanType)

        self.beginFilterGuard(vulkanType)
        self.doAllocSpace(vulkanType)

        if vulkanType.filterVar != None:
            print("onPointer Needs filter: %s filterVar %s" % (access, vulkanType.filterVar))

        if vulkanType.isHandleType() and self.mapHandles:
            self.genHandleMappingCall(
                vulkanType, access, lenAccess, lenAccessGuard)
        else:
            if self.typeInfo.isNonAbiPortableType(vulkanType.typeName):
                if lenAccess is not None:
                    if lenAccessGuard is not None:
                        self.cgen.beginIf(lenAccessGuard)
                    self.cgen.beginFor("uint32_t i = 0", "i < (uint32_t)%s" % lenAccess, "++i")
                    self.genPrimitiveStreamCall(vulkanType.getForValueAccess(), "%s[i]" % access)
                    self.cgen.endFor()
                    if lenAccessGuard is not None:
                        self.cgen.endIf()
                else:
                    self.genPrimitiveStreamCall(vulkanType.getForValueAccess(), "(*%s)" % access)
            else:
                if lenAccess is not None:
                    finalLenExpr = "%s * %s" % (
                        lenAccess, self.cgen.sizeofExpr(vulkanType.getForValueAccess()))
                else:
                    finalLenExpr = "%s" % (
                        self.cgen.sizeofExpr(vulkanType.getForValueAccess()))
                self.genStreamCall(vulkanType, access, finalLenExpr)

        if self.direction == "read":
            self.endFilterGuard(vulkanType, "%s = 0" % access)
        else:
            self.endFilterGuard(vulkanType)

    def onValue(self, vulkanType):
        self.beginFilterGuard(vulkanType)

        if vulkanType.isHandleType() and self.mapHandles:
            access = self.exprAccessor(vulkanType)
            if vulkanType.filterVar != None:
                print("onValue Needs filter: %s filterVar %s" % (access, vulkanType.filterVar))
            self.genHandleMappingCall(
                vulkanType.getForAddressAccess(), access, "1", None)
        elif self.typeInfo.isNonAbiPortableType(vulkanType.typeName):
            access = self.exprPrimitiveValueAccessor(vulkanType)
            self.genPrimitiveStreamCall(vulkanType, access)
        else:
            access = self.exprAccessor(vulkanType)
            self.genStreamCall(vulkanType, access, self.cgen.sizeofExpr(vulkanType))

        self.endFilterGuard(vulkanType)

    def streamLetParameter(self, structInfo, letParamInfo):
        filterFeature = "%s->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT" % self.streamVarName
        self.cgen.stmt("%s %s = 1" % (letParamInfo.typeName, letParamInfo.paramName))

        self.cgen.beginIf(filterFeature)

        if self.direction == "write":
            bodyExpr = self.currentStructInfo.environment[letParamInfo.paramName]["body"]
            self.cgen.stmt("%s = %s" % (letParamInfo.paramName, self.genFilterFunc(bodyExpr, self.currentStructInfo.environment)))

        self.genPrimitiveStreamCall(letParamInfo, letParamInfo.paramName)

        self.cgen.endIf()

class VulkanReservedMarshaling(VulkanWrapperGenerator):

    def __init__(self, module, typeInfo, variant="host"):
        VulkanWrapperGenerator.__init__(self, module, typeInfo)

        self.cgenHeader = CodeGen()
        self.cgenImpl = CodeGen()

        self.variant = variant

        self.currentFeature = None
        self.apiOpcodes = {}
        self.dynAlloc = self.variant != "guest"
        self.ptrVarName = "ptr"
        self.ptrVarType = makeVulkanTypeSimple(False, "uint8_t", 2, self.ptrVarName)
        self.ptrVarTypeUnmarshal = makeVulkanTypeSimple(False, "uint8_t", 2, self.ptrVarName)

        if self.variant == "guest":
            self.marshalingParams = PARAMETERS_MARSHALING_GUEST
        else:
            self.marshalingParams = PARAMETERS_MARSHALING

        self.writeCodegen = \
            VulkanReservedMarshalingCodegen(
                None,
                VULKAN_STREAM_VAR_NAME,
                ROOT_TYPE_VAR_NAME,
                MARSHAL_INPUT_VAR_NAME,
                self.ptrVarName,
                API_PREFIX_RESERVEDMARSHAL,
                "get_host_u64_" if "guest" == self.variant else "",
                direction = "write")

        self.readCodegen = \
            VulkanReservedMarshalingCodegen(
                None,
                VULKAN_STREAM_VAR_NAME,
                ROOT_TYPE_VAR_NAME,
                UNMARSHAL_INPUT_VAR_NAME,
                self.ptrVarName,
                API_PREFIX_RESERVEDUNMARSHAL,
                "unbox_" if "host" == self.variant else "",
                direction = "read",
                dynAlloc=self.dynAlloc)

        self.knownDefs = {}

        self.extensionMarshalPrototype = \
            VulkanAPI(API_PREFIX_RESERVEDMARSHAL + "extension_struct",
                      STREAM_RET_TYPE,
                      self.marshalingParams +
                      [STRUCT_EXTENSION_PARAM, self.ptrVarType])

        self.extensionUnmarshalPrototype = \
            VulkanAPI(API_PREFIX_RESERVEDUNMARSHAL + "extension_struct",
                      STREAM_RET_TYPE,
                      self.marshalingParams +
                      [STRUCT_EXTENSION_PARAM_FOR_WRITE, self.ptrVarTypeUnmarshal])

    def onBegin(self,):
        VulkanWrapperGenerator.onBegin(self)
        self.module.appendImpl(self.cgenImpl.makeFuncDecl(self.extensionMarshalPrototype))
        self.module.appendImpl(self.cgenImpl.makeFuncDecl(self.extensionUnmarshalPrototype))

    def onBeginFeature(self, featureName):
        VulkanWrapperGenerator.onBeginFeature(self, featureName)
        self.currentFeature = featureName

    def onGenType(self, typeXml, name, alias):
        VulkanWrapperGenerator.onGenType(self, typeXml, name, alias)

        if name in self.knownDefs:
            return

        category = self.typeInfo.categoryOf(name)

        if category in ["struct", "union"] and alias:
            if self.variant != "host":
                self.module.appendHeader(
                    self.cgenHeader.makeFuncAlias(API_PREFIX_RESERVEDMARSHAL + name,
                                                  API_PREFIX_RESERVEDMARSHAL + alias))
            if self.variant != "guest":
                self.module.appendHeader(
                    self.cgenHeader.makeFuncAlias(API_PREFIX_RESERVEDUNMARSHAL + name,
                                                  API_PREFIX_RESERVEDUNMARSHAL + alias))

        if category in ["struct", "union"] and not alias:

            structInfo = self.typeInfo.structs[name]

            marshalParams = self.marshalingParams + \
                [makeVulkanTypeSimple(True, name, 1, MARSHAL_INPUT_VAR_NAME),
                        self.ptrVarType]

            freeParams = []
            letParams = []

            for (envname, bindingInfo) in list(sorted(structInfo.environment.items(), key = lambda kv: kv[0])):
                if None == bindingInfo["binding"]:
                    freeParams.append(makeVulkanTypeSimple(True, bindingInfo["type"], 0, envname))
                else:
                    if not bindingInfo["structmember"]:
                        letParams.append(makeVulkanTypeSimple(True, bindingInfo["type"], 0, envname))

            marshalPrototype = \
                VulkanAPI(API_PREFIX_RESERVEDMARSHAL + name,
                          STREAM_RET_TYPE,
                          marshalParams + freeParams)

            marshalPrototypeNoFilter = \
                VulkanAPI(API_PREFIX_RESERVEDMARSHAL + name,
                          STREAM_RET_TYPE,
                          marshalParams)

            def structMarshalingCustom(cgen):
                self.writeCodegen.cgen = cgen
                self.writeCodegen.currentStructInfo = structInfo
                marshalingCode = \
                    CUSTOM_MARSHAL_TYPES[name]["common"] + \
                    CUSTOM_MARSHAL_TYPES[name]["reservedmarshaling"].format(
                        streamVarName=self.writeCodegen.streamVarName, 
                        rootTypeVarName=self.writeCodegen.rootTypeVarName,
                        inputVarName=self.writeCodegen.inputVarName,
                        newInputVarName=self.writeCodegen.inputVarName + "_new")
                for line in marshalingCode.split('\n'):
                    cgen.line(line)

            def structMarshalingDef(cgen):
                self.writeCodegen.cgen = cgen
                self.writeCodegen.currentStructInfo = structInfo
                self.writeCodegen.cgen.stmt("(void)%s" % VULKAN_STREAM_VAR_NAME)
                self.writeCodegen.cgen.stmt("(void)%s" % ROOT_TYPE_VAR_NAME)

                if category == "struct":
                    # marshal 'let' parameters first
                    for letp in letParams:
                        self.writeCodegen.streamLetParameter(self.typeInfo, letp)

                    for member in structInfo.members:
                        iterateVulkanType(self.typeInfo, member, self.writeCodegen)
                if category == "union":
                    iterateVulkanType(self.typeInfo, structInfo.members[0], self.writeCodegen)

            def structMarshalingDefNoFilter(cgen):
                self.writeCodegen.cgen = cgen
                self.writeCodegen.currentStructInfo = structInfo
                self.writeCodegen.doFiltering = False
                self.writeCodegen.cgen.stmt("(void)%s" % VULKAN_STREAM_VAR_NAME)
                self.writeCodegen.cgen.stmt("(void)%s" % ROOT_TYPE_VAR_NAME)

                if category == "struct":
                    # marshal 'let' parameters first
                    for letp in letParams:
                        self.writeCodegen.streamLetParameter(self.typeInfo, letp)

                    for member in structInfo.members:
                        iterateVulkanType(self.typeInfo, member, self.writeCodegen)
                if category == "union":
                    iterateVulkanType(self.typeInfo, structInfo.members[0], self.writeCodegen)
                self.writeCodegen.doFiltering = True

            if self.variant != "host":
                self.module.appendHeader(
                    self.cgenHeader.makeFuncDecl(marshalPrototype))

                if name in CUSTOM_MARSHAL_TYPES:
                    self.module.appendImpl(
                        self.cgenImpl.makeFuncImpl(
                            marshalPrototype, structMarshalingCustom))
                else:
                    self.module.appendImpl(
                        self.cgenImpl.makeFuncImpl(
                            marshalPrototype, structMarshalingDef))

                if freeParams != []:
                    self.module.appendHeader(
                        self.cgenHeader.makeFuncDecl(marshalPrototypeNoFilter))
                    self.module.appendImpl(
                        self.cgenImpl.makeFuncImpl(
                            marshalPrototypeNoFilter, structMarshalingDefNoFilter))

            unmarshalPrototype = \
                VulkanAPI(API_PREFIX_RESERVEDUNMARSHAL + name,
                          STREAM_RET_TYPE,
                          self.marshalingParams + [makeVulkanTypeSimple(False, name, 1, UNMARSHAL_INPUT_VAR_NAME), self.ptrVarTypeUnmarshal] + freeParams)

            unmarshalPrototypeNoFilter = \
                VulkanAPI(API_PREFIX_RESERVEDUNMARSHAL + name,
                          STREAM_RET_TYPE,
                          self.marshalingParams + [makeVulkanTypeSimple(False, name, 1, UNMARSHAL_INPUT_VAR_NAME), self.ptrVarTypeUnmarshal])

            def structUnmarshalingCustom(cgen):
                self.readCodegen.cgen = cgen
                self.readCodegen.currentStructInfo = structInfo
                unmarshalingCode = \
                    CUSTOM_MARSHAL_TYPES[name]["common"] + \
                    CUSTOM_MARSHAL_TYPES[name]["reservedunmarshaling"].format(
                        streamVarName=self.readCodegen.streamVarName, 
                        rootTypeVarName=self.readCodegen.rootTypeVarName,
                        inputVarName=self.readCodegen.inputVarName,
                        newInputVarName=self.readCodegen.inputVarName + "_new")
                for line in unmarshalingCode.split('\n'):
                    cgen.line(line)

            def structUnmarshalingDef(cgen):
                self.readCodegen.cgen = cgen
                self.readCodegen.currentStructInfo = structInfo
                if category == "struct":
                    # unmarshal 'let' parameters first
                    for letp in letParams:
                        self.readCodegen.streamLetParameter(self.typeInfo, letp)

                    for member in structInfo.members:
                        iterateVulkanType(self.typeInfo, member, self.readCodegen)
                if category == "union":
                    iterateVulkanType(self.typeInfo, structInfo.members[0], self.readCodegen)

            def structUnmarshalingDefNoFilter(cgen):
                self.readCodegen.cgen = cgen
                self.readCodegen.currentStructInfo = structInfo
                self.readCodegen.doFiltering = False
                if category == "struct":
                    # unmarshal 'let' parameters first
                    for letp in letParams:
                        iterateVulkanType(self.typeInfo, letp, self.readCodegen)
                    for member in structInfo.members:
                        iterateVulkanType(self.typeInfo, member, self.readCodegen)
                if category == "union":
                    iterateVulkanType(self.typeInfo, structInfo.members[0], self.readCodegen)
                self.readCodegen.doFiltering = True

            if self.variant != "guest":
                self.module.appendHeader(
                    self.cgenHeader.makeFuncDecl(unmarshalPrototype))

                if name in CUSTOM_MARSHAL_TYPES:
                    self.module.appendImpl(
                        self.cgenImpl.makeFuncImpl(
                            unmarshalPrototype, structUnmarshalingCustom))
                else:
                    self.module.appendImpl(
                        self.cgenImpl.makeFuncImpl(
                            unmarshalPrototype, structUnmarshalingDef))

                if freeParams != []:
                    self.module.appendHeader(
                        self.cgenHeader.makeFuncDecl(unmarshalPrototypeNoFilter))
                    self.module.appendImpl(
                        self.cgenImpl.makeFuncImpl(
                            unmarshalPrototypeNoFilter, structUnmarshalingDefNoFilter))

    def onGenCmd(self, cmdinfo, name, alias):
        VulkanWrapperGenerator.onGenCmd(self, cmdinfo, name, alias)

    def doExtensionStructMarshalingCodegen(self, cgen, retType, extParam, forEach, funcproto, direction):
        accessVar = "structAccess"
        sizeVar = "currExtSize"
        cgen.stmt("VkInstanceCreateInfo* %s = (VkInstanceCreateInfo*)(%s)" % (accessVar, extParam.paramName))
        cgen.stmt("uint32_t %s = %s(%s->getFeatureBits(), %s, %s)" % (sizeVar, EXTENSION_SIZE_WITH_STREAM_FEATURES_API_NAME, VULKAN_STREAM_VAR_NAME, ROOT_TYPE_VAR_NAME, extParam.paramName))

        cgen.beginIf("!%s && %s" % (sizeVar, extParam.paramName))

        cgen.line("// unknown struct extension; skip and call on its pNext field");
        cgen.funcCall(None, funcproto.name, ["vkStream", ROOT_TYPE_VAR_NAME, "(void*)%s->pNext" % accessVar, self.ptrVarName])
        cgen.stmt("return")

        cgen.endIf()
        cgen.beginElse()

        cgen.line("// known or null extension struct")

        if direction == "write":
            cgen.stmt("memcpy(*%s, &%s, sizeof(uint32_t));" % (self.ptrVarName, sizeVar))
            cgen.stmt("android::base::Stream::toBe32((uint8_t*)*%s); *%s += sizeof(uint32_t)" % (self.ptrVarName, self.ptrVarName))
        elif not self.dynAlloc:
            cgen.stmt("memcpy(&%s, *%s, sizeof(uint32_t));" % (sizeVar, self.ptrVarName))
            cgen.stmt("android::base::Stream::fromBe32((uint8_t*)&%s); *%s += sizeof(uint32_t)" % (sizeVar, self.ptrVarName))

        cgen.beginIf("!%s" % (sizeVar))
        cgen.line("// exit if this was a null extension struct (size == 0 in this branch)")
        cgen.stmt("return")
        cgen.endIf()

        cgen.endIf()

        # Now we can do stream stuff
        if direction == "write":
            cgen.stmt("memcpy(*%s, %s, sizeof(VkStructureType)); *%s += sizeof(VkStructureType)" % (self.ptrVarName, extParam.paramName, self.ptrVarName))
        elif not self.dynAlloc:
            cgen.stmt("uint64_t pNext_placeholder")
            placeholderAccess = "(&pNext_placeholder)"
            cgen.stmt("memcpy(%s, *%s, sizeof(VkStructureType)); *%s += sizeof(VkStructureType)" % (placeholderAccess, self.ptrVarName, self.ptrVarName))
            cgen.stmt("(void)pNext_placeholder")

        def fatalDefault(cgen):
            cgen.line("// fatal; the switch is only taken if the extension struct is known");
            cgen.stmt("abort()")
            pass

        self.emitForEachStructExtension(
            cgen,
            retType,
            extParam,
            forEach,
            defaultEmit=fatalDefault,
            rootTypeVar=ROOT_TYPE_PARAM)

    def onEnd(self,):
        VulkanWrapperGenerator.onEnd(self)

        def forEachExtensionMarshal(ext, castedAccess, cgen):
            cgen.funcCall(None, API_PREFIX_RESERVEDMARSHAL + ext.name,
                          [VULKAN_STREAM_VAR_NAME, ROOT_TYPE_VAR_NAME, castedAccess, self.ptrVarName])

        def forEachExtensionUnmarshal(ext, castedAccess, cgen):
            cgen.funcCall(None, API_PREFIX_RESERVEDUNMARSHAL + ext.name,
                          [VULKAN_STREAM_VAR_NAME, ROOT_TYPE_VAR_NAME, castedAccess, self.ptrVarName])

        if self.variant != "host":
            self.module.appendImpl(
                self.cgenImpl.makeFuncImpl(
                    self.extensionMarshalPrototype,
                    lambda cgen: self.doExtensionStructMarshalingCodegen(
                        cgen,
                        STREAM_RET_TYPE,
                        STRUCT_EXTENSION_PARAM,
                        forEachExtensionMarshal,
                        self.extensionMarshalPrototype,
                        "write")))

        if self.variant != "guest":
            self.module.appendImpl(
                self.cgenImpl.makeFuncImpl(
                    self.extensionUnmarshalPrototype,
                    lambda cgen: self.doExtensionStructMarshalingCodegen(
                        cgen,
                        STREAM_RET_TYPE,
                        STRUCT_EXTENSION_PARAM_FOR_WRITE,
                        forEachExtensionUnmarshal,
                        self.extensionUnmarshalPrototype,
                        "read")))
