/* Chordata - .NET File Format Parser
 * Copyright (C) 2001-2002  Jay Freeman (saurik)
*/

/*
 *        Redistribution and use in source and binary
 * forms, with or without modification, are permitted
 * provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the
 *    above copyright notice, this list of conditions
 *    and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the
 *    above copyright notice, this list of conditions
 *    and the following disclaimer in the documentation
 *    and/or other materials provided with the
 *    distribution.
 * 3. The name of the author may not be used to endorse
 *    or promote products derived from this software
 *    without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef CHORDATA_IMETADATAIMPORT_H
#define CHORDATA_IMETADATAIMPORT_H

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "menes-com/Unknown.h"
#include "chordata/Types.h"
#include "chordata/Tokens.h"

namespace Chordata {

DIAPEXIS_IFACE_(IMetaDataImport, Diapexis::Unknown) {
  public:
	virtual void DIAPEXIS_CALL CloseEnum(CorEnum hEnum) = 0;
    virtual HRESULT DIAPEXIS_CALL CountEnum(CorEnum hEnum, uint32_t *count) = 0;
    virtual HRESULT DIAPEXIS_CALL ResetEnum(CorEnum hEnum, uint32_t pos) = 0;

    virtual HRESULT DIAPEXIS_CALL EnumTypeDefs(CorEnum *phEnum, Tokens::mdTypeDef rTypeDefs[], uint32_t cMax, uint32_t *pcTypeDefs) = 0;
    virtual HRESULT DIAPEXIS_CALL EnumInterfaceImpls(CorEnum *phEnum, Tokens::mdTypeDef td, Tokens::mdInterfaceImpl rImpls[], uint32_t cMax, uint32_t *pcImpls) = 0;
    virtual HRESULT DIAPEXIS_CALL EnumTypeRefs(CorEnum *phEnum, Tokens::mdTypeRef rTypeRefs[], uint32_t cMax, uint32_t *pcTypeRefs) = 0;

    virtual HRESULT DIAPEXIS_CALL FindTypeDefByName(wcstr_t szTypeDef, Token tkEnclosingClass, Tokens::mdTypeDef *ptd) = 0;
    virtual HRESULT DIAPEXIS_CALL GetScopeProps(wstr_t szName, uint32_t cchName, uint32_t *pchName, GUID *pmvid) = 0;

    virtual HRESULT DIAPEXIS_CALL GetModuleFromScope(Tokens::mdModule *pmd) = 0;

    virtual HRESULT DIAPEXIS_CALL GetTypeDefProps(Tokens::mdTypeDef td, wstr_t szTypeDef, uint32_t cchTypeDef, uint32_t *pchTypeDef, uint32_t *pdwTypeDefFlags, Token *ptkExtends) = 0;
    virtual HRESULT DIAPEXIS_CALL GetInterfaceImplProps(Tokens::mdInterfaceImpl iiImpl, Tokens::mdTypeDef *pClass, Token *ptkIface) = 0;

    virtual HRESULT DIAPEXIS_CALL GetTypeRefProps(Tokens::mdTypeRef tr, Token *ptkResolutionScope, wstr_t szName, uint32_t cchName, uint32_t *pchName) = 0;
    virtual HRESULT DIAPEXIS_CALL ResolveTypeRef(Tokens::mdTypeRef tr, REFIID riid, Diapexis::Unknown **ppIScope, Tokens::mdTypeDef *ptd) = 0;

    virtual HRESULT DIAPEXIS_CALL EnumMembers(CorEnum *phEnum, Tokens::mdTypeDef cl, Token rMembers[], uint32_t cMax, uint32_t *pcTokens) = 0;
    virtual HRESULT DIAPEXIS_CALL EnumMembersWithName(CorEnum *phEnum, Tokens::mdTypeDef cl, wcstr_t szName, Token rMembers[], uint32_t cMax, uint32_t *pcTokens) = 0;

    virtual HRESULT DIAPEXIS_CALL EnumMethods(CorEnum *phEnum, Tokens::mdTypeDef cl, Tokens::mdMethodDef rMethods[], uint32_t cMax, uint32_t *pcTokens) = 0;
    virtual HRESULT DIAPEXIS_CALL EnumMethodsWithName(CorEnum *phEnum, Tokens::mdTypeDef cl, wcstr_t szName, Tokens::mdMethodDef rMethods[], uint32_t cMax, uint32_t *pcTokens) = 0;

	virtual HRESULT DIAPEXIS_CALL EnumFields(CorEnum *phEnum, Tokens::mdTypeDef cl, Tokens::mdFieldDef rFields[], uint32_t cMax, uint32_t *pcTokens) = 0;
    virtual HRESULT DIAPEXIS_CALL EnumFieldsWithName(CorEnum *phEnum, Tokens::mdTypeDef cl, wcstr_t szName, Tokens::mdFieldDef rFields[], uint32_t cMax, uint32_t *pcTokens) = 0;

    virtual HRESULT DIAPEXIS_CALL EnumParams(CorEnum *phEnum, Tokens::mdMethodDef mb, Tokens::mdParamDef rParams[], uint32_t cMax, uint32_t *pcTokens) = 0;
    virtual HRESULT DIAPEXIS_CALL EnumMemberRefs(CorEnum *phEnum, Token tkParent, Tokens::mdMemberRef rMemberRefs[], uint32_t cMax, uint32_t *pcTokens) = 0;
    virtual HRESULT DIAPEXIS_CALL EnumMethodImpls(CorEnum *phEnum, Tokens::mdTypeDef td, Token rMethodBody[], Token rMethodDecl[], uint32_t cMax, uint32_t *pcTokens) = 0;
    virtual HRESULT DIAPEXIS_CALL EnumPermissionSets(CorEnum *phEnum, Token tk, uint32_t dwActions, Tokens::mdPermission rPermission[], uint32_t cMax, uint32_t *pcTokens) = 0;

    virtual HRESULT DIAPEXIS_CALL FindMember(Tokens::mdTypeDef td, wcstr_t name, const Signature *pvSigBlob, uint32_t cbSigBlob, Token *pmb) = 0;
    virtual HRESULT DIAPEXIS_CALL FindMethod(Tokens::mdTypeDef td, wcstr_t name, const Signature *pvSigBlob, uint32_t cbSigBlob, Tokens::mdMethodDef *pmb) = 0;
    virtual HRESULT DIAPEXIS_CALL FindField(Tokens::mdTypeDef td, wcstr_t name, const Signature *pvSigBlob, uint32_t cbSigBlob, Tokens::mdFieldDef *pmb) = 0;
    virtual HRESULT DIAPEXIS_CALL FindMemberRef(Tokens::mdTypeRef td, wcstr_t szName, const Signature *pvSigBlob, uint32_t cbSigBlob, Tokens::mdMemberRef *pmr) = 0;

    virtual HRESULT DIAPEXIS_CALL GetMethodProps(Tokens::mdMethodDef mb, Tokens::mdTypeDef *pClass, wstr_t szMethod, uint32_t cchMethod, uint32_t *pchMethod, uint32_t *pdwAttr, const Signature **ppvSigBlob, uint32_t *pcbSigBlob, uint32_t *pulCodeRVA, uint32_t *pdwImplFlags) = 0;
    virtual HRESULT DIAPEXIS_CALL GetMemberRefProps(Tokens::mdMemberRef mr, Token *ptk, wstr_t szMember, uint32_t cchMember, uint32_t *pchMember, const Signature **ppvSigBlob, uint32_t *pbSig) = 0;

    virtual HRESULT DIAPEXIS_CALL EnumProperties(CorEnum *phEnum, Tokens::mdTypeDef td, Tokens::mdProperty rProperties[], uint32_t cMax, uint32_t *pcProperties) = 0;
    virtual HRESULT DIAPEXIS_CALL EnumEvents(CorEnum *phEnum, Tokens::mdTypeDef td, Tokens::mdEvent rEvents[], uint32_t cMax, uint32_t *pcEvents) = 0;

    virtual HRESULT DIAPEXIS_CALL GetEventProps(Tokens::mdEvent ev, Tokens::mdTypeDef *pClass, wcstr_t szEvent, uint32_t cchEvent, uint32_t *pchEvent, uint32_t *pdwEventFlags, Token *ptkEventType, Tokens::mdMethodDef *pmdAddOn, Tokens::mdMethodDef *pmdRemoveOn, Tokens::mdMethodDef *pmdFire, Tokens::mdMethodDef rmdOtherMethod[], uint32_t cMax, uint32_t *pcOtherMethod) = 0;

    virtual HRESULT DIAPEXIS_CALL EnumMethodSemantics(CorEnum *phEnum, Tokens::mdMethodDef mb, Token rEventProp[], uint32_t cMax, uint32_t *pcEventProp) = 0;
    virtual HRESULT DIAPEXIS_CALL GetMethodSemantics(Tokens::mdMethodDef mb, Token tkEventProp, uint32_t *pdwSemanticsFlags) = 0;

    virtual HRESULT DIAPEXIS_CALL GetClassLayout(Tokens::mdTypeDef td, uint32_t *pdwPackSize, FieldOffset rFieldOffset[], uint32_t cMax, uint32_t *pcFieldOffset, uint32_t *pulClassSize) = 0;
    virtual HRESULT DIAPEXIS_CALL GetFieldMarshal(Token tk, const Signature **ppvNativeType, uint32_t *pcbNativeType) = 0;

    virtual HRESULT DIAPEXIS_CALL GetRVA(Token tk, uint32_t *pulCodeRVA, uint32_t *pdwImplFlags) = 0;

    virtual HRESULT DIAPEXIS_CALL GetPermissionSetProps(Tokens::mdPermission pm, uint32_t *pdwAction, void const **ppvPermission, uint32_t *pcbPermission) = 0;
    virtual HRESULT DIAPEXIS_CALL GetSigFromToken(Tokens::mdSignature mdSig, const Signature **ppvSig, uint32_t *pcbSig) = 0;

    virtual HRESULT DIAPEXIS_CALL GetModuleRefProps(Tokens::mdModuleRef mur, wchar_t *szName, uint32_t cchName, uint32_t *pchName) = 0;
    virtual HRESULT DIAPEXIS_CALL EnumModuleRefs(CorEnum *phEnum, Tokens::mdModuleRef rModuleRefs[], uint32_t cmax, uint32_t *pcModuleRefs) = 0;

    virtual HRESULT DIAPEXIS_CALL GetTypeSpecFromToken(Tokens::mdTypeSpec typespec, const Signature **ppvSig, uint32_t *pcbSig) = 0;
    virtual HRESULT DIAPEXIS_CALL GetNameFromToken(Token tk, cstr_t *pszUtf8NamePtr) = 0;

    virtual HRESULT DIAPEXIS_CALL EnumUnresolvedMethods(CorEnum *phEnum, Token rMethods[], uint32_t cMax, uint32_t *pcTokens) = 0;

	virtual HRESULT DIAPEXIS_CALL GetUserString(Tokens::mdString stk, wstr_t szString, uint32_t cchString, uint32_t *pchString) = 0;
    virtual HRESULT DIAPEXIS_CALL GetPinvokeMap(Token tk, uint32_t *pdwMappingFlags, wstr_t szImportName, uint32_t cchImportName, uint32_t *pchImportName, Tokens::mdModuleRef *pmrImportDLL) = 0;

    virtual HRESULT DIAPEXIS_CALL EnumSignatures(CorEnum *phEnum, Tokens::mdSignature rSignatures[], uint32_t cmax, uint32_t *pcSignatures) = 0;
    virtual HRESULT DIAPEXIS_CALL EnumTypeSpecs(CorEnum *phEnum, Tokens::mdTypeSpec rTypeSpecs[], uint32_t cmax, uint32_t *pcTypeSpecs) = 0;
    virtual HRESULT DIAPEXIS_CALL EnumUserStrings(CorEnum *phEnum, Tokens::mdString rStrings[], uint32_t cmax, uint32_t *pcStrings) = 0;

    virtual HRESULT DIAPEXIS_CALL GetParamForMethodIndex(Tokens::mdMethodDef md, uint32_t ulParamSeq, Tokens::mdParamDef *ppd) = 0;

	virtual HRESULT DIAPEXIS_CALL EnumCustomAttributes(CorEnum *phEnum, Token tk, Token tkType, Tokens::mdCustomAttribute rCustomAttributes[], uint32_t cMax, uint32_t *pcCustomAttributes) = 0;
	virtual HRESULT DIAPEXIS_CALL GetCustomAttributeProps(Tokens::mdCustomAttribute cv, Token *ptkObj, Token *ptkType, void const **ppBlob, uint32_t *pcbSize) = 0;

    virtual HRESULT DIAPEXIS_CALL FindTypeRef(Token tkResolutionScope, wcstr_t szName, Tokens::mdTypeRef *ptr) = 0;

    virtual HRESULT DIAPEXIS_CALL GetMemberProps(Token mb, Tokens::mdTypeDef *pClass, wstr_t szMember, uint32_t cchMember, uint32_t *pchMember, uint32_t *pdwAttr, const Signature **ppvSigBlob, uint32_t *pcbSigBlob, uint32_t *pulCodeRVA, uint32_t *pdwImplFlags, uint32_t *pdwCPlusTypeFlag, void const **ppValue, uint32_t *pcchValue) = 0;
    virtual HRESULT DIAPEXIS_CALL GetFieldProps(Tokens::mdFieldDef mb, Tokens::mdTypeDef *pClass, wstr_t szField, uint32_t cchField, uint32_t *pchField, uint32_t *pdwAttr, const Signature **ppvSigBlob, uint32_t *pcbSigBlob, uint32_t *pdwCPlusTypeFlag, void const **ppValue, uint32_t *pcchValue) = 0;
    virtual HRESULT DIAPEXIS_CALL GetPropertyProps(Tokens::mdProperty prop, Tokens::mdTypeDef *pClass, wstr_t szProperty, uint32_t cchProperty, uint32_t *pchProperty, uint32_t *pdwPropFlags, const Signature **ppvSig, uint32_t *pbSig, uint32_t *pdwCPlusTypeFlag, void const **ppDefaultValue, uint32_t *pcbDefaultValue, Tokens::mdMethodDef *pmdSetter, Tokens::mdMethodDef *pmdGetter, Tokens::mdMethodDef rmdOtherMethod[], uint32_t cMax, uint32_t *pcOtherMethod) = 0;
    virtual HRESULT DIAPEXIS_CALL GetParamProps(Tokens::mdParamDef tk, Tokens::mdMethodDef *pmd, uint32_t *pulSequence, wstr_t szName, uint32_t cchName, uint32_t *pchName, uint32_t *pdwAttr, uint32_t *pdwCPlusTypeFlag, void const **ppValue, uint32_t *pcchValue) = 0;

    virtual HRESULT DIAPEXIS_CALL GetCustomAttributeByName(Token tkObj, wcstr_t szName, const void **ppData, uint32_t *pcbData) = 0;

    virtual BOOL DIAPEXIS_CALL IsValidToken(Token tk) = 0;

    virtual HRESULT DIAPEXIS_CALL GetNestedClassProps(Tokens::mdTypeDef tdNestedClass, Tokens::mdTypeDef *ptdEnclosingClass) = 0;
    virtual HRESULT DIAPEXIS_CALL GetNativeCallConvFromSig(void const *pvSig, uint32_t cbSig, uint32_t *pCallConv) = 0;

	virtual HRESULT DIAPEXIS_CALL IsGlobal(Token pd, int32_t *pbGlobal) = 0;
};

}

#endif CHORDATA_IMETADATAIMPORT_H