mirror of
https://github.com/titanscouting/tra-analysis.git
synced 2025-02-12 05:15:47 +00:00
177 lines
5.9 KiB
JavaScript
177 lines
5.9 KiB
JavaScript
"use strict";
|
|
module.exports = verifier;
|
|
|
|
var Enum = require("./enum"),
|
|
util = require("./util");
|
|
|
|
function invalid(field, expected) {
|
|
return field.name + ": " + expected + (field.repeated && expected !== "array" ? "[]" : field.map && expected !== "object" ? "{k:"+field.keyType+"}" : "") + " expected";
|
|
}
|
|
|
|
/**
|
|
* Generates a partial value verifier.
|
|
* @param {Codegen} gen Codegen instance
|
|
* @param {Field} field Reflected field
|
|
* @param {number} fieldIndex Field index
|
|
* @param {string} ref Variable reference
|
|
* @returns {Codegen} Codegen instance
|
|
* @ignore
|
|
*/
|
|
function genVerifyValue(gen, field, fieldIndex, ref) {
|
|
/* eslint-disable no-unexpected-multiline */
|
|
if (field.resolvedType) {
|
|
if (field.resolvedType instanceof Enum) { gen
|
|
("switch(%s){", ref)
|
|
("default:")
|
|
("return%j", invalid(field, "enum value"));
|
|
for (var keys = Object.keys(field.resolvedType.values), j = 0; j < keys.length; ++j) gen
|
|
("case %i:", field.resolvedType.values[keys[j]]);
|
|
gen
|
|
("break")
|
|
("}");
|
|
} else {
|
|
gen
|
|
("{")
|
|
("var e=types[%i].verify(%s);", fieldIndex, ref)
|
|
("if(e)")
|
|
("return%j+e", field.name + ".")
|
|
("}");
|
|
}
|
|
} else {
|
|
switch (field.type) {
|
|
case "int32":
|
|
case "uint32":
|
|
case "sint32":
|
|
case "fixed32":
|
|
case "sfixed32": gen
|
|
("if(!util.isInteger(%s))", ref)
|
|
("return%j", invalid(field, "integer"));
|
|
break;
|
|
case "int64":
|
|
case "uint64":
|
|
case "sint64":
|
|
case "fixed64":
|
|
case "sfixed64": gen
|
|
("if(!util.isInteger(%s)&&!(%s&&util.isInteger(%s.low)&&util.isInteger(%s.high)))", ref, ref, ref, ref)
|
|
("return%j", invalid(field, "integer|Long"));
|
|
break;
|
|
case "float":
|
|
case "double": gen
|
|
("if(typeof %s!==\"number\")", ref)
|
|
("return%j", invalid(field, "number"));
|
|
break;
|
|
case "bool": gen
|
|
("if(typeof %s!==\"boolean\")", ref)
|
|
("return%j", invalid(field, "boolean"));
|
|
break;
|
|
case "string": gen
|
|
("if(!util.isString(%s))", ref)
|
|
("return%j", invalid(field, "string"));
|
|
break;
|
|
case "bytes": gen
|
|
("if(!(%s&&typeof %s.length===\"number\"||util.isString(%s)))", ref, ref, ref)
|
|
("return%j", invalid(field, "buffer"));
|
|
break;
|
|
}
|
|
}
|
|
return gen;
|
|
/* eslint-enable no-unexpected-multiline */
|
|
}
|
|
|
|
/**
|
|
* Generates a partial key verifier.
|
|
* @param {Codegen} gen Codegen instance
|
|
* @param {Field} field Reflected field
|
|
* @param {string} ref Variable reference
|
|
* @returns {Codegen} Codegen instance
|
|
* @ignore
|
|
*/
|
|
function genVerifyKey(gen, field, ref) {
|
|
/* eslint-disable no-unexpected-multiline */
|
|
switch (field.keyType) {
|
|
case "int32":
|
|
case "uint32":
|
|
case "sint32":
|
|
case "fixed32":
|
|
case "sfixed32": gen
|
|
("if(!util.key32Re.test(%s))", ref)
|
|
("return%j", invalid(field, "integer key"));
|
|
break;
|
|
case "int64":
|
|
case "uint64":
|
|
case "sint64":
|
|
case "fixed64":
|
|
case "sfixed64": gen
|
|
("if(!util.key64Re.test(%s))", ref) // see comment above: x is ok, d is not
|
|
("return%j", invalid(field, "integer|Long key"));
|
|
break;
|
|
case "bool": gen
|
|
("if(!util.key2Re.test(%s))", ref)
|
|
("return%j", invalid(field, "boolean key"));
|
|
break;
|
|
}
|
|
return gen;
|
|
/* eslint-enable no-unexpected-multiline */
|
|
}
|
|
|
|
/**
|
|
* Generates a verifier specific to the specified message type.
|
|
* @param {Type} mtype Message type
|
|
* @returns {Codegen} Codegen instance
|
|
*/
|
|
function verifier(mtype) {
|
|
/* eslint-disable no-unexpected-multiline */
|
|
|
|
var gen = util.codegen(["m"], mtype.name + "$verify")
|
|
("if(typeof m!==\"object\"||m===null)")
|
|
("return%j", "object expected");
|
|
var oneofs = mtype.oneofsArray,
|
|
seenFirstField = {};
|
|
if (oneofs.length) gen
|
|
("var p={}");
|
|
|
|
for (var i = 0; i < /* initializes */ mtype.fieldsArray.length; ++i) {
|
|
var field = mtype._fieldsArray[i].resolve(),
|
|
ref = "m" + util.safeProp(field.name);
|
|
|
|
if (field.optional) gen
|
|
("if(%s!=null&&m.hasOwnProperty(%j)){", ref, field.name); // !== undefined && !== null
|
|
|
|
// map fields
|
|
if (field.map) { gen
|
|
("if(!util.isObject(%s))", ref)
|
|
("return%j", invalid(field, "object"))
|
|
("var k=Object.keys(%s)", ref)
|
|
("for(var i=0;i<k.length;++i){");
|
|
genVerifyKey(gen, field, "k[i]");
|
|
genVerifyValue(gen, field, i, ref + "[k[i]]")
|
|
("}");
|
|
|
|
// repeated fields
|
|
} else if (field.repeated) { gen
|
|
("if(!Array.isArray(%s))", ref)
|
|
("return%j", invalid(field, "array"))
|
|
("for(var i=0;i<%s.length;++i){", ref);
|
|
genVerifyValue(gen, field, i, ref + "[i]")
|
|
("}");
|
|
|
|
// required or present fields
|
|
} else {
|
|
if (field.partOf) {
|
|
var oneofProp = util.safeProp(field.partOf.name);
|
|
if (seenFirstField[field.partOf.name] === 1) gen
|
|
("if(p%s===1)", oneofProp)
|
|
("return%j", field.partOf.name + ": multiple values");
|
|
seenFirstField[field.partOf.name] = 1;
|
|
gen
|
|
("p%s=1", oneofProp);
|
|
}
|
|
genVerifyValue(gen, field, i, ref);
|
|
}
|
|
if (field.optional) gen
|
|
("}");
|
|
}
|
|
return gen
|
|
("return null");
|
|
/* eslint-enable no-unexpected-multiline */
|
|
} |