bool Generator::outputModifiedResponseImplementation()

in src/ClientGenerator.cpp [712:801]


bool Generator::outputModifiedResponseImplementation(std::ostream& sourceFile,
	const std::string& outerScope, const ResponseField& responseField) const noexcept
{
	std::ostringstream oss;

	oss << outerScope << R"cpp(::)cpp" << getResponseFieldCppType(responseField);

	const auto cppType = oss.str();
	std::unordered_set<std::string_view> fieldNames;

	switch (responseField.type->kind())
	{
		case introspection::TypeKind::OBJECT:
		case introspection::TypeKind::INTERFACE:
		case introspection::TypeKind::UNION:
		{
			for (const auto& field : responseField.children)
			{
				if (fieldNames.emplace(field.name).second)
				{
					outputModifiedResponseImplementation(sourceFile, cppType, field);
				}
			}
			break;
		}

		default:
			// This is a scalar type, it doesn't require a type declaration.
			return false;
	}

	fieldNames.clear();

	// This is a complex type that requires a custom ModifiedResponse implementation.
	sourceFile << R"cpp(
template <>
)cpp" << cppType
			   << R"cpp( ModifiedResponse<)cpp" << cppType
			   << R"cpp(>::parse(response::Value response)
{
	)cpp" << cppType
			   << R"cpp( result;

	if (response.type() == response::Type::Map)
	{
		auto members = response.release<response::MapType>();

		for (auto& member : members)
		{
)cpp";

	switch (responseField.type->kind())
	{
		case introspection::TypeKind::OBJECT:
		case introspection::TypeKind::INTERFACE:
		case introspection::TypeKind::UNION:
		{
			for (const auto& field : responseField.children)
			{
				if (fieldNames.emplace(field.name).second)
				{
					sourceFile << R"cpp(			if (member.first == R"js()cpp" << field.name
							   << R"cpp()js"sv)
			{
				result.)cpp" << field.cppName
							   << R"cpp( = ModifiedResponse<)cpp"
							   << getResponseFieldCppType(field, cppType) << R"cpp(>::parse)cpp"
							   << getTypeModifierList(field.modifiers)
							   << R"cpp((std::move(member.second));
				continue;
			}
)cpp";
				}
			}
			break;
		}

		default:
			break;
	}

	sourceFile << R"cpp(		}
	}

	return result;
}
)cpp";

	return true;
}