|
"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"; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function genVerifyValue(gen, field, fieldIndex, ref) { |
|
|
|
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; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function genVerifyKey(gen, field, ref) { |
|
|
|
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) |
|
("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; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
function verifier(mtype) { |
|
|
|
|
|
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 < 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); |
|
|
|
|
|
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]]") |
|
("}"); |
|
|
|
|
|
} 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]") |
|
("}"); |
|
|
|
|
|
} 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"); |
|
|
|
} |