/*
 * Copyright 2018 Arm Limited
 *
 * 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.
 */

#ifndef SPIRV_CROSS_PARSER_HPP
#define SPIRV_CROSS_PARSER_HPP

#include "spirv_cross_parsed_ir.hpp"
#include <stdint.h>
#include <vector>

namespace spirv_cross
{
class Parser
{
public:
	Parser(const uint32_t *spirv_data, size_t word_count);
	Parser(std::vector<uint32_t> spirv);

	void parse();

	ParsedIR &get_parsed_ir()
	{
		return ir;
	}

private:
	ParsedIR ir;
	SPIRFunction *current_function = nullptr;
	SPIRBlock *current_block = nullptr;

	void parse(const Instruction &instr);
	const uint32_t *stream(const Instruction &instr) const;

	template <typename T, typename... P>
	T &set(uint32_t id, P &&... args)
	{
		auto &var = variant_set<T>(ir.ids.at(id), std::forward<P>(args)...);
		var.self = id;
		return var;
	}

	template <typename T>
	T &get(uint32_t id)
	{
		return variant_get<T>(ir.ids.at(id));
	}

	template <typename T>
	T *maybe_get(uint32_t id)
	{
		if (ir.ids.at(id).get_type() == T::type)
			return &get<T>(id);
		else
			return nullptr;
	}

	template <typename T>
	const T &get(uint32_t id) const
	{
		return variant_get<T>(ir.ids.at(id));
	}

	template <typename T>
	const T *maybe_get(uint32_t id) const
	{
		if (ir.ids.at(id).get_type() == T::type)
			return &get<T>(id);
		else
			return nullptr;
	}

	// This must be an ordered data structure so we always pick the same type aliases.
	std::vector<uint32_t> global_struct_cache;

	bool types_are_logically_equivalent(const SPIRType &a, const SPIRType &b) const;
	bool variable_storage_is_aliased(const SPIRVariable &v) const;
	void make_constant_null(uint32_t id, uint32_t type);
};
} // namespace spirv_cross

#endif
