/* 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_IMETADATAEMIT_H
#define CHORDATA_IMETADATAEMIT_H

#if _MSC_VER > 1000
#pragma once
#endif

#include "menes-com/Unknown.h"
#include "menes-com/String.h"

#include "chordata/Tokens.h"
#include "chordata/IMapToken.h"

#include "chordata/IMetaDataAssemblyEmit.h"
#include "chordata/IMetaDataAssemblyImport.h"
#include "chordata/IMetaDataImport.h"

namespace Chordata {

DIAPEXIS_IFACE_(IMetaDataEmit, Diapexis::Unknown) {
	STDMETHOD(SetModuleProps)(wcstr_t name) = 0;
	STDMETHOD(Save)(wcstr_t file, uint32_t flags) = 0;
	STDMETHOD(SaveToStream)(IStream *stream, uint32_t flags) = 0;
	STDMETHOD(GetSaveSize)(CorSaveSize type, uint32_t *size) = 0;

	STDMETHOD(DefineTypeDef)(wcstr_t name, uint32_t flags, Token extends, Token implements[], Tokens::mdTypeDef *token) = 0;
	STDMETHOD(DefineNestedType)(wcstr_t name, uint32_t flags, Token extends, Token implements[], Tokens::mdTypeDef encloser, Tokens::mdTypeDef *token) = 0;
	STDMETHOD(SetHandler)(IUnknown *unknown) = 0;

	STDMETHOD(DefineMethod)(Tokens::mdTypeDef type, wcstr_t name, uint32_t methodFlags, const Signature *sigBlob, uint32_t sigLength, uint32_t rva, uint32_t implFlags, Tokens::mdMethodDef *token) = 0;
	STDMETHOD(DefineMethodImpl)(Tokens::mdTypeDef td, Token body, Token decl) = 0;
	STDMETHOD(DefineTypeRefByName)(Token scope, wcstr_t name, Tokens::mdTypeRef *token) = 0;
	STDMETHOD(DefineImportType)(IMetaDataAssemblyImport *pAssemImport, const void *pbHashValue, uint32_t cbHashValue, IMetaDataImport *pImport, Tokens::mdTypeDef tdImport, IMetaDataAssemblyEmit *pAssemEmit, Tokens::mdTypeRef *ptr) = 0;
	STDMETHOD(DefineMemberRef)(Token encloser, wcstr_t name, const Signature *sigBlob, uint32_t sigLength, Tokens::mdMemberRef *token) = 0;
	STDMETHOD(DefineImportMember)(IMetaDataAssemblyImport *asmImport, const void *hashValue, uint32_t hashLength, IMetaDataImport *import, Token member, IMetaDataAssemblyEmit *asmEmit, Token parent, Tokens::mdMemberRef *token) = 0;
	STDMETHOD(DefineEvent) (Tokens::mdTypeDef td, wcstr_t szEvent, uint32_t dwEventFlags, Token tkEventType, Tokens::mdMethodDef mdAddOn, Tokens::mdMethodDef mdRemoveOn, Tokens::mdMethodDef mdFire, Tokens::mdMethodDef rmdOtherMethods[], Tokens::mdEvent *mdEvent) = 0;

	STDMETHOD(SetClassLayout) (Tokens::mdTypeDef td, uint32_t dwPackSize, FieldOffset rFieldOffsets[], uint32_t ulClassSize) = 0;
	STDMETHOD(DeleteClassLayout) (Tokens::mdTypeDef td) = 0;
	STDMETHOD(SetFieldMarshal) (Token tk, const Signature *pvNativeType, uint32_t cbNativeType) = 0;
	STDMETHOD(DeleteFieldMarshal) (Token tk) = 0;

	STDMETHOD(DefinePermissionSet) (Token tk, uint32_t dwAction, void const *pvPermission, uint32_t cbPermission, Tokens::mdPermission *ppm) = 0;

	STDMETHOD(SetRVA)(Tokens::mdMethodDef md, int32_t ulRVA) = 0;
	STDMETHOD(GetTokenFromSig)(const Signature *pvSig, uint32_t cbSig, Tokens::mdSignature *pmsig) = 0;
	STDMETHOD(DefineModuleRef)(wcstr_t szName, Tokens::mdModuleRef *pmur) = 0;
	STDMETHOD(SetParent)(Tokens::mdMemberRef mr, Token tk) = 0;
	STDMETHOD(GetTokenFromTypeSpec)(const Signature *pvSig, uint32_t cbSig, Tokens::mdTypeSpec *ptypespec) = 0;
	STDMETHOD(SaveToMemory)(void *pbData, uint32_t cbData) = 0;
	STDMETHOD(DefineUserString)(wcstr_t string, uint32_t length, Tokens::mdString *token) = 0;
	STDMETHOD(DeleteToken)(Token token) = 0;
	STDMETHOD(SetMethodProps)(Tokens::mdMethodDef method, uint32_t methodFlags, uint32_t rva, uint32_t implFlags) = 0;
	STDMETHOD(SetTypeDefProps)(Tokens::mdTypeDef type, uint32_t typeFlags, Token extends, Token implements[]) = 0;
	STDMETHOD(SetEventProps)(Tokens::mdEvent event, uint32_t eventFlags, Token eventType, Tokens::mdMethodDef add, Tokens::mdMethodDef remove, Tokens::mdMethodDef fire, Tokens::mdMethodDef others[]) = 0;
	STDMETHOD(SetPermissionSetProps)(Token object, uint32_t action, void const *permission, uint32_t length, Tokens::mdPermission *token) = 0;

	STDMETHOD(DefinePinvokeMap)(Token member, uint32_t mapFlags, wcstr_t name, Tokens::mdModuleRef dll) = 0;
	STDMETHOD(SetPinvokeMap)(Token member, uint32_t mapFlags, wcstr_t name, Tokens::mdModuleRef dll) = 0;
	STDMETHOD(DeletePinvokeMap)(Token tk) = 0;

	STDMETHOD(DefineCustomAttribute)(Token tkObj, Token tkType, void const *pCustomAttribute, uint32_t cbCustomAttribute, Tokens::mdCustomAttribute *pcv) = 0;
	STDMETHOD(SetCustomAttributeValue)(Tokens::mdCustomAttribute pcv, void const *pCustomAttribute, uint32_t cbCustomAttribute) = 0;

	STDMETHOD(DefineField)(Tokens::mdTypeDef type, wcstr_t name, uint32_t fieldFlags, const Signature *sigBlob, uint32_t sigLength, uint32_t cppType, void const *cppValue, uint32_t cppLength, Tokens::mdFieldDef *token) = 0;
	STDMETHOD(DefineProperty)(Tokens::mdTypeDef type, wcstr_t name, uint32_t propFlags, const Signature *sigBlob, uint32_t sigLength, uint32_t cppType, void const *cppValue, uint32_t cppLength, Tokens::mdMethodDef setter, Tokens::mdMethodDef getter, Tokens::mdMethodDef others[], Tokens::mdProperty *token) = 0;
	STDMETHOD(DefineParam)(Tokens::mdMethodDef md, uint32_t ulParamSeq, wcstr_t szName, uint32_t dwParamFlags, uint32_t dwCPlusTypeFlag, void const *pValue, uint32_t cchValue, Tokens::mdParamDef *ppd) = 0;

	STDMETHOD(SetFieldProps)(Tokens::mdFieldDef fd, uint32_t dwFieldFlags, uint32_t dwCPlusTypeFlag, void const *pValue, uint32_t cchValue) = 0;
	STDMETHOD(SetPropertyProps)(Tokens::mdProperty pr, uint32_t dwPropFlags, uint32_t dwCPlusTypeFlag, void const *pValue, uint32_t cchValue, Tokens::mdMethodDef mdSetter, Tokens::mdMethodDef mdGetter, Tokens::mdMethodDef rmdOtherMethods[]) = 0;
	STDMETHOD(SetParamProps)(Tokens::mdParamDef pd, wcstr_t szName, uint32_t dwParamFlags, uint32_t dwCPlusTypeFlag, void const *pValue, uint32_t cchValue) = 0;

	STDMETHOD(DefineSecurityAttributeSet)(Token tkObj, SecurityAttribute rSecAttrs[], uint32_t cSecAttrs, uint32_t *pulErrorAttr) = 0;
	STDMETHOD(ApplyEditAndContinue)(IUnknown *import) = 0;
	STDMETHOD(TranslateSigWithScope)(IMetaDataAssemblyImport *pAssemImport, const void *pbHashValue, uint32_t cbHashValue, IMetaDataImport *import, const Signature *pbSigBlob, uint32_t cbSigBlob, IMetaDataAssemblyEmit *pAssemEmit, IMetaDataEmit *emit, const Signature *pvTranslatedSig, uint32_t cbTranslatedSigMax, uint32_t *pcbTranslatedSig) = 0;
	STDMETHOD(SetMethodImplFlags)(Tokens::mdMethodDef method, uint32_t implFlags) = 0;
	STDMETHOD(SetFieldRVA)(Tokens::mdFieldDef field, uint32_t rva) = 0;

	STDMETHOD(Merge)(IMetaDataImport *import, IMapToken *map, IUnknown *handler) = 0;
	STDMETHOD(MergeEnd)() = 0;

};

}

#endif CHORDATA_IMETADATAEMIT_H