#include "TypeQualifiers.hpp"

namespace core {

abstraction::TypeQualifiers::TypeQualifierSet xmlApi < abstraction::TypeQualifiers::TypeQualifierSet >::parse ( ext::deque < sax::Token >::iterator & input ) {
	sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::START_ELEMENT, xmlTagName ( ) );

	abstraction::TypeQualifiers::TypeQualifierSet res = abstraction::TypeQualifiers::TypeQualifierSet::NONE;

	while ( sax::FromXMLParserHelper::isToken ( input, sax::Token::TokenType::START_ELEMENT, "entry" ) ) {
		sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::START_ELEMENT, "entry" );

		std::string data = sax::FromXMLParserHelper::popTokenData(input, sax::Token::TokenType::CHARACTER);
		if ( data == "lref" )
			res = res | abstraction::TypeQualifiers::TypeQualifierSet::LREF;
		else if ( data == "rref" )
			res = res | abstraction::TypeQualifiers::TypeQualifierSet::RREF;
		else if ( data == "const" )
			res = res | abstraction::TypeQualifiers::TypeQualifierSet::CONST;
		else
			throw exception::CommonException ( "Invalid param qualifier." );

		sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::END_ELEMENT, "entry" );
	}
	sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::END_ELEMENT, xmlTagName ( ) );

	return res;
}

bool xmlApi < abstraction::TypeQualifiers::TypeQualifierSet >::first ( const ext::deque < sax::Token >::const_iterator & input ) {
	return sax::FromXMLParserHelper::isToken(input, sax::Token::TokenType::START_ELEMENT, xmlTagName ( ) );
}

std::string xmlApi < abstraction::TypeQualifiers::TypeQualifierSet >::xmlTagName ( ) {
	return "TypeQualifierSet";
}

void xmlApi < abstraction::TypeQualifiers::TypeQualifierSet >::compose ( ext::deque < sax::Token > & output, abstraction::TypeQualifiers::TypeQualifierSet typeQualifiers ) {
	output.emplace_back ( xmlTagName ( ), sax::Token::TokenType::START_ELEMENT);
	if ( abstraction::TypeQualifiers::isConst ( typeQualifiers ) ) {
		output.emplace_back ( "entry", sax::Token::TokenType::START_ELEMENT);
		output.emplace_back ( "const", sax::Token::TokenType::CHARACTER);
		output.emplace_back ( "entry", sax::Token::TokenType::END_ELEMENT);
	}
	if ( abstraction::TypeQualifiers::isLvalueRef ( typeQualifiers ) ) {
		output.emplace_back ( "entry", sax::Token::TokenType::START_ELEMENT);
		output.emplace_back ( "lref", sax::Token::TokenType::CHARACTER);
		output.emplace_back ( "entry", sax::Token::TokenType::END_ELEMENT);
	}
	if ( abstraction::TypeQualifiers::isRvalueRef ( typeQualifiers ) ) {
		output.emplace_back ( "entry", sax::Token::TokenType::START_ELEMENT);
		output.emplace_back ( "rref", sax::Token::TokenType::CHARACTER);
		output.emplace_back ( "entry", sax::Token::TokenType::END_ELEMENT);
	}
	output.emplace_back ( xmlTagName ( ), sax::Token::TokenType::END_ELEMENT);
}

} /* namespace core */
