<commit_before>'use strict';

var combiner = require('stream-combiner');
var lodash = require('engine-lodash');
var path = require('path');
var plugins = require('gulp-load-plugins')();
var soyparser = require('soyparser');
var templates = require('../templates');
var through = require('through2');

var namespaces = {};
var templateParams = {};

function generateSoy() {
	namespaces = {};
	templateParams = {};
	return generateTemplatesAndExtractParams();
}

function compileSoy(options) {
	return combiner(
		plugins.soynode({
			loadCompiledTemplates: false,
			locales: options.soyLocales,
			messageFilePathFormat: options.soyMessageFilePathFormat,
			shouldDeclareTopLevelNamespaces: false
		}),
		plugins.ignore.exclude('*.soy'),
		plugins.wrapper({
			header: getHeaderContent(options.corePathFromSoy),
			footer: getFooterContent
		})
	);
}

module.exports.generateSoy = generateSoy;
module.exports.compileSoy = compileSoy;

// Private helpers
function addTemplateParam(soyJsPath, namespace, templateName, param) {
	templateName = namespace + '.' + templateName;
	templateParams[soyJsPath] = templateParams[soyJsPath] || {};
	templateParams[soyJsPath][templateName] = templateParams[soyJsPath][templateName] || [];
	templateParams[soyJsPath][templateName].push(param);
}

function createComponentElementSoy(moduleName, hasElementTemplate) {
	var soy = '';
	if (!hasElementTemplate) {
		soy += lodash.renderSync(templates.ModuleNameElement, {
			className: moduleName.toLowerCase(),
			moduleName: moduleName
		});
	}
	return soy;
}

function createComponentSoy(moduleName) {
	return lodash.renderSync(templates.ModuleName, {
		moduleName: moduleName
	});
}

function createSurfaceElementSoy(moduleName, surfaceName, hasElementTemplate) {
	if (!hasElementTemplate) {
		return lodash.renderSync(templates.SurfaceElement, {
			moduleName: moduleName,
			surfaceName: surfaceName
		});
	}
	return '';
}

function createSurfaceSoy(moduleName, surfaceName) {
	return lodash.renderSync(templates.Surface, {
		moduleName: moduleName,
		surfaceName: surfaceName
	});
}

function generateDelTemplate(namespace, templateName, hasElementTemplate) {
	var moduleName = namespace.substr(10);
	if (templateName === 'content') {
		return createComponentSoy(moduleName) +
			createComponentElementSoy(moduleName, hasElementTemplate);
	} else {
		return createSurfaceElementSoy(moduleName, templateName, hasElementTemplate) +
			createSurfaceSoy(moduleName, templateName);
	}
}

function generateTemplatesAndExtractParams() {
	return through.obj(function(file, encoding, callback) {
		var fileString = file.contents.toString(encoding);
		fileString += '\n// The following templates were generated by gulp-metal.\n' +
			'// Please don\'t edit them by hand.\n';

		var parsed = soyparser(file.contents);
		var namespace = parsed.namespace;
		var moduleName = namespace.substr(10);
		var hasElementTemplateMap = getHasElementTemplateMap(parsed.templates);
		var soyJsPath = file.relative + '.js';

		namespaces[soyJsPath] = namespace;
		parsed.templates.forEach(function(cmd) {
			if (cmd.deltemplate || cmd.attributes.private === 'true') {
				return;
			}

			var fullName = cmd.name === 'content' ? moduleName : moduleName + '.' + cmd.name;
			fileString += generateDelTemplate(namespace, cmd.name, hasElementTemplateMap[fullName]);

			cmd.params.forEach(function(tag) {
				if (tag.name !== '?') {
					addTemplateParam(soyJsPath, namespace, cmd.name, tag.name);
				}
			});
		});

		file.contents = new Buffer(fileString);
		this.push(file);
		callback();
	});
}

function getFilenameNoLocale(filename) {
	return filename.replace(/_[^.]+\.soy/, '.soy');
}

function getFooterContent(file) {
	var footer = '';
	var pathNoLocale = getFilenameNoLocale(file.relative);
	var fileParams = templateParams[pathNoLocale];
	for (var templateName in fileParams) {
		footer += '\n' + templateName + '.params = ' + JSON.stringify(fileParams[templateName]) + ';';
	}
	footer += '\nexport default ' + namespaces[pathNoLocale] + ';';
	return footer + '\n/* jshint ignore:end */\n';
}

function getHasElementTemplateMap(templateCmds) {
	var hasElementTemplateMap = {};
	templateCmds.forEach(function(cmd) {
		if (cmd.deltemplate && cmd.attributes.variant === '\'element\'') {
			hasElementTemplateMap[cmd.name] = true;
		}
	});
	return hasElementTemplateMap;
}

function getHeaderContent(corePathFromSoy) {
	return function(file) {
		var corePath = corePathFromSoy;
		if (typeof corePath === 'function') {
			corePath = corePathFromSoy(file);
		}
		var registryModulePath = path.join(corePath, '/component/ComponentRegistry');
		return '/* jshint ignore:start */\n' +
			'import ComponentRegistry from \'' + registryModulePath + '\';\n' +
			'var Templates = ComponentRegistry.Templates;\n';
	};
}
<commit_msg>Changes soy compilation to always set the params var for templates that will be used as surfaces<commit_after>'use strict';

var combiner = require('stream-combiner');
var lodash = require('engine-lodash');
var path = require('path');
var plugins = require('gulp-load-plugins')();
var soyparser = require('soyparser');
var templates = require('../templates');
var through = require('through2');

var namespaces = {};
var templateParams = {};

function generateSoy() {
	namespaces = {};
	templateParams = {};
	return generateTemplatesAndExtractParams();
}

function compileSoy(options) {
	return combiner(
		plugins.soynode({
			loadCompiledTemplates: false,
			locales: options.soyLocales,
			messageFilePathFormat: options.soyMessageFilePathFormat,
			shouldDeclareTopLevelNamespaces: false
		}),
		plugins.ignore.exclude('*.soy'),
		plugins.wrapper({
			header: getHeaderContent(options.corePathFromSoy),
			footer: getFooterContent
		})
	);
}

module.exports.generateSoy = generateSoy;
module.exports.compileSoy = compileSoy;

// Private helpers
function addTemplateParam(soyJsPath, templateName, param) {
	templateParams[soyJsPath][templateName].push(param);
}

function createComponentElementSoy(moduleName, hasElementTemplate) {
	var soy = '';
	if (!hasElementTemplate) {
		soy += lodash.renderSync(templates.ModuleNameElement, {
			className: moduleName.toLowerCase(),
			moduleName: moduleName
		});
	}
	return soy;
}

function createComponentSoy(moduleName) {
	return lodash.renderSync(templates.ModuleName, {
		moduleName: moduleName
	});
}

function createSurfaceElementSoy(moduleName, surfaceName, hasElementTemplate) {
	if (!hasElementTemplate) {
		return lodash.renderSync(templates.SurfaceElement, {
			moduleName: moduleName,
			surfaceName: surfaceName
		});
	}
	return '';
}

function createSurfaceSoy(moduleName, surfaceName) {
	return lodash.renderSync(templates.Surface, {
		moduleName: moduleName,
		surfaceName: surfaceName
	});
}

function generateDelTemplate(namespace, templateName, hasElementTemplate) {
	var moduleName = namespace.substr(10);
	if (templateName === 'content') {
		return createComponentSoy(moduleName) +
			createComponentElementSoy(moduleName, hasElementTemplate);
	} else {
		return createSurfaceElementSoy(moduleName, templateName, hasElementTemplate) +
			createSurfaceSoy(moduleName, templateName);
	}
}

function generateTemplatesAndExtractParams() {
	return through.obj(function(file, encoding, callback) {
		var fileString = file.contents.toString(encoding);
		fileString += '\n// The following templates were generated by gulp-metal.\n' +
			'// Please don\'t edit them by hand.\n';

		var parsed = soyparser(file.contents);
		var namespace = parsed.namespace;
		var moduleName = namespace.substr(10);
		var hasElementTemplateMap = getHasElementTemplateMap(parsed.templates);
		var soyJsPath = file.relative + '.js';

		namespaces[soyJsPath] = namespace;
		templateParams[soyJsPath] = {};
		parsed.templates.forEach(function(cmd) {
			if (cmd.deltemplate || cmd.attributes.private === 'true') {
				return;
			}

			var fullName = cmd.name === 'content' ? moduleName : moduleName + '.' + cmd.name;
			fileString += generateDelTemplate(namespace, cmd.name, hasElementTemplateMap[fullName]);

			var templateName = namespace + '.' + cmd.name;
			templateParams[soyJsPath][templateName] = [];
			cmd.params.forEach(function(tag) {
				if (tag.name !== '?') {
					addTemplateParam(soyJsPath, templateName, tag.name);
				}
			});
		});

		file.contents = new Buffer(fileString);
		this.push(file);
		callback();
	});
}

function getFilenameNoLocale(filename) {
	return filename.replace(/_[^.]+\.soy/, '.soy');
}

function getFooterContent(file) {
	var footer = '';
	var pathNoLocale = getFilenameNoLocale(file.relative);
	var fileParams = templateParams[pathNoLocale];
	for (var templateName in fileParams) {
		footer += '\n' + templateName + '.params = ' + JSON.stringify(fileParams[templateName]) + ';';
	}
	footer += '\nexport default ' + namespaces[pathNoLocale] + ';';
	return footer + '\n/* jshint ignore:end */\n';
}

function getHasElementTemplateMap(templateCmds) {
	var hasElementTemplateMap = {};
	templateCmds.forEach(function(cmd) {
		if (cmd.deltemplate && cmd.attributes.variant === '\'element\'') {
			hasElementTemplateMap[cmd.name] = true;
		}
	});
	return hasElementTemplateMap;
}

function getHeaderContent(corePathFromSoy) {
	return function(file) {
		var corePath = corePathFromSoy;
		if (typeof corePath === 'function') {
			corePath = corePathFromSoy(file);
		}
		var registryModulePath = path.join(corePath, '/component/ComponentRegistry');
		return '/* jshint ignore:start */\n' +
			'import ComponentRegistry from \'' + registryModulePath + '\';\n' +
			'var Templates = ComponentRegistry.Templates;\n';
	};
}

{'fraction_non_alphanumeric': 0.13471177944862156, 'fraction_numerical': 0.0010442773600668337, 'mean_word_length': 5.214795587280986, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4698501', 'n_tokens_mistral': 3135, 'n_tokens_neox': 2930, 'n_words': 579}