UNPKG

@apollo/protobufjs

Version:

Protocol Buffers for JavaScript (& TypeScript).

191 lines (180 loc) 6.6 kB
"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) { var arrayRef = ref; if (field.useToArray()) { arrayRef = "array" + field.id; gen("var %s", arrayRef); gen("if (%s!=null&&%s.toArray) { %s = %s.toArray() } else { %s = %s }", ref, ref, arrayRef, ref, arrayRef, ref); } gen ("if(!Array.isArray(%s))", arrayRef) ("return%j", invalid(field, "array")) ("for(var i=0;i<%s.length;++i){", arrayRef); if (field.preEncoded()) { gen("if (!(%s instanceof Uint8Array)) {", arrayRef + "[i]") } genVerifyValue(gen, field, i, arrayRef + "[i]") if (field.preEncoded()) { gen("}"); } gen("}"); // 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 */ }