UNPKG

@odata/parser

Version:
1,111 lines 37.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.floorMethodCallExpr = exports.roundMethodCallExpr = exports.nowMethodCallExpr = exports.maxDateTimeMethodCallExpr = exports.minDateTimeMethodCallExpr = exports.totalOffsetMinutesMethodCallExpr = exports.timeMethodCallExpr = exports.dateMethodCallExpr = exports.totalsecondsMethodCallExpr = exports.fractionalsecondsMethodCallExpr = exports.secondMethodCallExpr = exports.minuteMethodCallExpr = exports.hourMethodCallExpr = exports.dayMethodCallExpr = exports.monthMethodCallExpr = exports.yearMethodCallExpr = exports.concatMethodCallExpr = exports.trimMethodCallExpr = exports.toUpperMethodCallExpr = exports.toLowerMethodCallExpr = exports.substringOfMethodCallExpr = exports.substringMethodCallExpr = exports.indexOfMethodCallExpr = exports.lengthMethodCallExpr = exports.endsWithMethodCallExpr = exports.startsWithMethodCallExpr = exports.containsMethodCallExpr = exports.methodCallExprFactory = exports.methodCallExpr = exports.boolMethodCallExpr = exports.parenExpr = exports.boolParenExpr = exports.notExpr = exports.modExpr = exports.divExpr = exports.mulExpr = exports.subExpr = exports.addExpr = exports.hasExpr = exports.geExpr = exports.gtExpr = exports.leExpr = exports.ltExpr = exports.neExpr = exports.eqExpr = exports.leftRightExpr = exports.orExpr = exports.andExpr = exports.boolCommonExpr = exports.commonExpr = void 0; exports.rootExpr = exports.valueExpr = exports.refExpr = exports.countExpr = exports.parameterValue = exports.parameterAlias = exports.parameterName = exports.functionExprParameter = exports.functionExprParameters = exports.boundFunctionExpr = exports.functionExpr = exports.singlePathExpr = exports.complexPathExpr = exports.collectionPathExpr = exports.singleNavigationExpr = exports.keyPropertyAlias = exports.keyPropertyValue = exports.keyValuePair = exports.compoundKey = exports.simpleKey = exports.keyPredicate = exports.collectionNavigationExpr = exports.allExpr = exports.anyExpr = exports.lambdaPredicateExpr = exports.lambdaVariableExpr = exports.implicitVariableExpr = exports.inscopeVariableExpr = exports.propertyPathExpr = exports.memberExpr = exports.firstMemberExpr = exports.negateExpr = exports.castExpr = exports.isofExpr = exports.intersectsMethodCallExpr = exports.geoLengthMethodCallExpr = exports.distanceMethodCallExpr = exports.ceilingMethodCallExpr = void 0; const ArrayOrObject = require("./json"); const Lexer = require("./lexer"); const NameOrIdentifier = require("./nameOrIdentifier"); const PrimitiveLiteral = require("./primitiveLiteral"); const utils_1 = require("./utils"); function commonExpr(value, index) { const token = PrimitiveLiteral.primitiveLiteral(value, index) || parameterAlias(value, index) || ArrayOrObject.arrayOrObject(value, index) || rootExpr(value, index) || methodCallExpr(value, index) || firstMemberExpr(value, index) || functionExpr(value, index) || negateExpr(value, index) || parenExpr(value, index) || castExpr(value, index); if (!token) { return; } const expr = addExpr(value, token.next) || subExpr(value, token.next) || mulExpr(value, token.next) || divExpr(value, token.next) || modExpr(value, token.next); if (expr) { token.value = { left: Lexer.clone(token), right: expr.value }; token.next = expr.value.next; token.type = expr.type; token.raw = utils_1.default.stringify(value, token.position, token.next); } if (token) { return Lexer.tokenize(value, token.position, token.next, token, Lexer.TokenType.CommonExpression); } } exports.commonExpr = commonExpr; function boolCommonExpr(value, index) { const token = isofExpr(value, index) || boolMethodCallExpr(value, index) || notExpr(value, index) || commonExpr(value, index) || boolParenExpr(value, index); if (!token) { return; } let commonMoreExpr = undefined; if (token.type === Lexer.TokenType.CommonExpression) { commonMoreExpr = eqExpr(value, token.next) || neExpr(value, token.next) || ltExpr(value, token.next) || leExpr(value, token.next) || gtExpr(value, token.next) || geExpr(value, token.next) || hasExpr(value, token.next); if (commonMoreExpr) { token.value = { left: token.value, right: commonMoreExpr.value }; token.next = commonMoreExpr.value.next; token.type = commonMoreExpr.type; token.raw = utils_1.default.stringify(value, token.position, token.next); } } const expr = andExpr(value, token.next) || orExpr(value, token.next); if (expr) { const left = Lexer.clone(token); token.next = expr.value.next; token.value = { left, right: expr.value }; token.type = expr.type; token.raw = utils_1.default.stringify(value, token.position, token.next); if (token.type === Lexer.TokenType.AndExpression && token.value.right.type === Lexer.TokenType.OrExpression) { token.value.left = Lexer.tokenize(value, token.value.left.position, token.value.right.value.left.next, { left: token.value.left, right: token.value.right.value.left }, token.type); token.type = token.value.right.type; token.value.right = token.value.right.value.right; } } return token; } exports.boolCommonExpr = boolCommonExpr; function andExpr(value, index) { let rws = Lexer.RWS(value, index); if (rws === index || !utils_1.default.equals(value, rws, 'and')) { return; } const start = index; index = rws + 3; rws = Lexer.RWS(value, index); if (rws === index) { return; } index = rws; const token = boolCommonExpr(value, index); if (!token) { return; } return Lexer.tokenize(value, start, index, token, Lexer.TokenType.AndExpression); } exports.andExpr = andExpr; function orExpr(value, index) { let rws = Lexer.RWS(value, index); if (rws === index || !utils_1.default.equals(value, rws, 'or')) { return; } const start = index; index = rws + 2; rws = Lexer.RWS(value, index); if (rws === index) { return; } index = rws; const token = boolCommonExpr(value, index); if (!token) { return; } return Lexer.tokenize(value, start, index, token, Lexer.TokenType.OrExpression); } exports.orExpr = orExpr; function leftRightExpr(value, index, expr, tokenType) { let rws = Lexer.RWS(value, index); if (rws === index) { return; } const start = index; index = rws; if (!utils_1.default.equals(value, index, expr)) { return; } index += expr.length; rws = Lexer.RWS(value, index); if (rws === index) { return; } index = rws; const token = commonExpr(value, index); if (!token) { return; } return Lexer.tokenize(value, start, index, token.value, tokenType); } exports.leftRightExpr = leftRightExpr; function eqExpr(value, index) { return leftRightExpr(value, index, 'eq', Lexer.TokenType.EqualsExpression); } exports.eqExpr = eqExpr; function neExpr(value, index) { return leftRightExpr(value, index, 'ne', Lexer.TokenType.NotEqualsExpression); } exports.neExpr = neExpr; function ltExpr(value, index) { return leftRightExpr(value, index, 'lt', Lexer.TokenType.LesserThanExpression); } exports.ltExpr = ltExpr; function leExpr(value, index) { return leftRightExpr(value, index, 'le', Lexer.TokenType.LesserOrEqualsExpression); } exports.leExpr = leExpr; function gtExpr(value, index) { return leftRightExpr(value, index, 'gt', Lexer.TokenType.GreaterThanExpression); } exports.gtExpr = gtExpr; function geExpr(value, index) { return leftRightExpr(value, index, 'ge', Lexer.TokenType.GreaterOrEqualsExpression); } exports.geExpr = geExpr; function hasExpr(value, index) { return leftRightExpr(value, index, 'has', Lexer.TokenType.HasExpression); } exports.hasExpr = hasExpr; function addExpr(value, index) { return leftRightExpr(value, index, 'add', Lexer.TokenType.AddExpression); } exports.addExpr = addExpr; function subExpr(value, index) { return leftRightExpr(value, index, 'sub', Lexer.TokenType.SubExpression); } exports.subExpr = subExpr; function mulExpr(value, index) { return leftRightExpr(value, index, 'mul', Lexer.TokenType.MulExpression); } exports.mulExpr = mulExpr; function divExpr(value, index) { return leftRightExpr(value, index, 'div', Lexer.TokenType.DivExpression); } exports.divExpr = divExpr; function modExpr(value, index) { return leftRightExpr(value, index, 'mod', Lexer.TokenType.ModExpression); } exports.modExpr = modExpr; function notExpr(value, index) { if (!utils_1.default.equals(value, index, 'not')) { return; } const start = index; index += 3; const rws = Lexer.RWS(value, index); if (rws === index) { return; } index = rws; const token = boolCommonExpr(value, index); if (!token) { return; } return Lexer.tokenize(value, start, token.next, token, Lexer.TokenType.NotExpression); } exports.notExpr = notExpr; function boolParenExpr(value, index) { const open = Lexer.OPEN(value, index); if (!open) { return; } const start = index; index = open; index = Lexer.BWS(value, index); const token = boolCommonExpr(value, index); if (!token) { return; } index = Lexer.BWS(value, token.next); const close = Lexer.CLOSE(value, index); if (!close) { return; } index = close; return Lexer.tokenize(value, start, index, token, Lexer.TokenType.BoolParenExpression); } exports.boolParenExpr = boolParenExpr; function parenExpr(value, index) { const open = Lexer.OPEN(value, index); if (!open) { return; } const start = index; index = open; index = Lexer.BWS(value, index); const token = commonExpr(value, index); if (!token) { return; } index = Lexer.BWS(value, token.next); const close = Lexer.CLOSE(value, index); if (!close) { return; } index = close; return Lexer.tokenize(value, start, index, token.value, Lexer.TokenType.ParenExpression); } exports.parenExpr = parenExpr; function boolMethodCallExpr(value, index) { return (endsWithMethodCallExpr(value, index) || startsWithMethodCallExpr(value, index) || containsMethodCallExpr(value, index) || intersectsMethodCallExpr(value, index)); } exports.boolMethodCallExpr = boolMethodCallExpr; function methodCallExpr(value, index) { return (indexOfMethodCallExpr(value, index) || toLowerMethodCallExpr(value, index) || toUpperMethodCallExpr(value, index) || trimMethodCallExpr(value, index) || substringMethodCallExpr(value, index) || substringOfMethodCallExpr(value, index) || concatMethodCallExpr(value, index) || lengthMethodCallExpr(value, index) || yearMethodCallExpr(value, index) || monthMethodCallExpr(value, index) || dayMethodCallExpr(value, index) || hourMethodCallExpr(value, index) || minuteMethodCallExpr(value, index) || secondMethodCallExpr(value, index) || fractionalsecondsMethodCallExpr(value, index) || totalsecondsMethodCallExpr(value, index) || dateMethodCallExpr(value, index) || timeMethodCallExpr(value, index) || roundMethodCallExpr(value, index) || floorMethodCallExpr(value, index) || ceilingMethodCallExpr(value, index) || distanceMethodCallExpr(value, index) || geoLengthMethodCallExpr(value, index) || totalOffsetMinutesMethodCallExpr(value, index) || minDateTimeMethodCallExpr(value, index) || maxDateTimeMethodCallExpr(value, index) || nowMethodCallExpr(value, index)); } exports.methodCallExpr = methodCallExpr; function methodCallExprFactory(value, index, method, min, max) { if (typeof min === 'undefined') { min = 0; } if (typeof max === 'undefined') { max = min; } if (!utils_1.default.equals(value, index, method)) { return; } const start = index; index += method.length; const open = Lexer.OPEN(value, index); if (!open) { return; } index = open; index = Lexer.BWS(value, index); let parameters; if (min > 0) { parameters = []; while (parameters.length < max) { const expr = commonExpr(value, index); if (parameters.length < min && !expr) { return; } else if (expr) { parameters.push(expr.value); index = expr.next; index = Lexer.BWS(value, index); const comma = Lexer.COMMA(value, index); if (parameters.length < min && !comma) { return; } if (comma) { index = comma; } else { break; } index = Lexer.BWS(value, index); } else { break; } } } index = Lexer.BWS(value, index); const close = Lexer.CLOSE(value, index); if (!close) { return; } index = close; return Lexer.tokenize(value, start, index, { method, parameters }, Lexer.TokenType.MethodCallExpression); } exports.methodCallExprFactory = methodCallExprFactory; function containsMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'contains', 2); } exports.containsMethodCallExpr = containsMethodCallExpr; function startsWithMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'startswith', 2); } exports.startsWithMethodCallExpr = startsWithMethodCallExpr; function endsWithMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'endswith', 2); } exports.endsWithMethodCallExpr = endsWithMethodCallExpr; function lengthMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'length', 1); } exports.lengthMethodCallExpr = lengthMethodCallExpr; function indexOfMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'indexof', 2); } exports.indexOfMethodCallExpr = indexOfMethodCallExpr; function substringMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'substring', 2, 3); } exports.substringMethodCallExpr = substringMethodCallExpr; function substringOfMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'substringof', 2); } exports.substringOfMethodCallExpr = substringOfMethodCallExpr; function toLowerMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'tolower', 1); } exports.toLowerMethodCallExpr = toLowerMethodCallExpr; function toUpperMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'toupper', 1); } exports.toUpperMethodCallExpr = toUpperMethodCallExpr; function trimMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'trim', 1); } exports.trimMethodCallExpr = trimMethodCallExpr; function concatMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'concat', 2); } exports.concatMethodCallExpr = concatMethodCallExpr; function yearMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'year', 1); } exports.yearMethodCallExpr = yearMethodCallExpr; function monthMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'month', 1); } exports.monthMethodCallExpr = monthMethodCallExpr; function dayMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'day', 1); } exports.dayMethodCallExpr = dayMethodCallExpr; function hourMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'hour', 1); } exports.hourMethodCallExpr = hourMethodCallExpr; function minuteMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'minute', 1); } exports.minuteMethodCallExpr = minuteMethodCallExpr; function secondMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'second', 1); } exports.secondMethodCallExpr = secondMethodCallExpr; function fractionalsecondsMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'fractionalseconds', 1); } exports.fractionalsecondsMethodCallExpr = fractionalsecondsMethodCallExpr; function totalsecondsMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'totalseconds', 1); } exports.totalsecondsMethodCallExpr = totalsecondsMethodCallExpr; function dateMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'date', 1); } exports.dateMethodCallExpr = dateMethodCallExpr; function timeMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'time', 1); } exports.timeMethodCallExpr = timeMethodCallExpr; function totalOffsetMinutesMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'totaloffsetminutes', 1); } exports.totalOffsetMinutesMethodCallExpr = totalOffsetMinutesMethodCallExpr; function minDateTimeMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'mindatetime', 0); } exports.minDateTimeMethodCallExpr = minDateTimeMethodCallExpr; function maxDateTimeMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'maxdatetime', 0); } exports.maxDateTimeMethodCallExpr = maxDateTimeMethodCallExpr; function nowMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'now', 0); } exports.nowMethodCallExpr = nowMethodCallExpr; function roundMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'round', 1); } exports.roundMethodCallExpr = roundMethodCallExpr; function floorMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'floor', 1); } exports.floorMethodCallExpr = floorMethodCallExpr; function ceilingMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'ceiling', 1); } exports.ceilingMethodCallExpr = ceilingMethodCallExpr; function distanceMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'geo.distance', 2); } exports.distanceMethodCallExpr = distanceMethodCallExpr; function geoLengthMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'geo.length', 1); } exports.geoLengthMethodCallExpr = geoLengthMethodCallExpr; function intersectsMethodCallExpr(value, index) { return methodCallExprFactory(value, index, 'geo.intersects', 2); } exports.intersectsMethodCallExpr = intersectsMethodCallExpr; function isofExpr(value, index) { if (!utils_1.default.equals(value, index, 'isof')) { return; } const start = index; index += 4; const open = Lexer.OPEN(value, index); if (!open) { return; } index = open; index = Lexer.BWS(value, index); const expr = commonExpr(value, index); if (expr) { index = expr.next; index = Lexer.BWS(value, index); const comma = Lexer.COMMA(value, index); if (!comma) { return; } index = comma; index = Lexer.BWS(value, index); } const typeName = NameOrIdentifier.qualifiedTypeName(value, index); if (!typeName) { return; } index = typeName.next; index = Lexer.BWS(value, index); const close = Lexer.CLOSE(value, index); if (!close) { return; } index = close; return Lexer.tokenize(value, start, index, { target: expr, typename: typeName }, Lexer.TokenType.IsOfExpression); } exports.isofExpr = isofExpr; function castExpr(value, index) { if (!utils_1.default.equals(value, index, 'cast')) { return; } const start = index; index += 4; const open = Lexer.OPEN(value, index); if (!open) { return; } index = open; index = Lexer.BWS(value, index); const expr = commonExpr(value, index); if (expr) { index = expr.next; index = Lexer.BWS(value, index); const comma = Lexer.COMMA(value, index); if (!comma) { return; } index = comma; index = Lexer.BWS(value, index); } const typeName = NameOrIdentifier.qualifiedTypeName(value, index); if (!typeName) { return; } index = typeName.next; index = Lexer.BWS(value, index); const close = Lexer.CLOSE(value, index); if (!close) { return; } index = close; return Lexer.tokenize(value, start, index, { target: expr, typename: typeName }, Lexer.TokenType.CastExpression); } exports.castExpr = castExpr; function negateExpr(value, index) { if (value[index] !== 0x2d) { return; } const start = index; index++; index = Lexer.BWS(value, index); const expr = commonExpr(value, index); if (!expr) { return; } return Lexer.tokenize(value, start, expr.next, expr, Lexer.TokenType.NegateExpression); } exports.negateExpr = negateExpr; function firstMemberExpr(value, index) { let token = inscopeVariableExpr(value, index); let member; const start = index; if (token) { if (value[token.next] === 0x2f) { index = token.next + 1; member = memberExpr(value, index); if (!member) { return; } return Lexer.tokenize(value, start, member.next, [token, member], Lexer.TokenType.FirstMemberExpression); } } else { member = memberExpr(value, index); } token = token || member; if (!token) { return; } return Lexer.tokenize(value, start, token.next, token, Lexer.TokenType.FirstMemberExpression); } exports.firstMemberExpr = firstMemberExpr; function memberExpr(value, index) { const start = index; const token = NameOrIdentifier.qualifiedEntityTypeName(value, index); if (token) { if (value[token.next] !== 0x2f) { return; } index = token.next + 1; } const next = propertyPathExpr(value, index) || boundFunctionExpr(value, index); if (!next) { return; } return Lexer.tokenize(value, start, next.next, token ? { name: token, value: next } : next, Lexer.TokenType.MemberExpression); } exports.memberExpr = memberExpr; function propertyPathExpr(value, index) { let token = NameOrIdentifier.odataIdentifier(value, index); const start = index; if (token) { index = token.next; const nav = collectionPathExpr(value, token.next) || collectionNavigationExpr(value, token.next) || singleNavigationExpr(value, token.next) || complexPathExpr(value, token.next) || singlePathExpr(value, token.next); if (nav) { index = nav.next; token = { current: Lexer.clone(token), next: nav }; } } else if (!token) { token = NameOrIdentifier.streamProperty(value, index); if (token) { index = token.next; } } if (!token) { return; } return Lexer.tokenize(value, start, index, token, Lexer.TokenType.PropertyPathExpression); } exports.propertyPathExpr = propertyPathExpr; function inscopeVariableExpr(value, index) { return (implicitVariableExpr(value, index) || (isLambdaPredicate ? lambdaVariableExpr(value, index) : undefined)); } exports.inscopeVariableExpr = inscopeVariableExpr; function implicitVariableExpr(value, index) { if (utils_1.default.equals(value, index, '$it')) { return Lexer.tokenize(value, index, index + 3, '$it', Lexer.TokenType.ImplicitVariableExpression); } } exports.implicitVariableExpr = implicitVariableExpr; let isLambdaPredicate = false; let hasLambdaVariableExpr = false; function lambdaVariableExpr(value, index) { const token = NameOrIdentifier.odataIdentifier(value, index, Lexer.TokenType.LambdaVariableExpression); if (token) { hasLambdaVariableExpr = true; return token; } } exports.lambdaVariableExpr = lambdaVariableExpr; function lambdaPredicateExpr(value, index) { isLambdaPredicate = true; const token = boolCommonExpr(value, index); isLambdaPredicate = false; if (token && hasLambdaVariableExpr) { hasLambdaVariableExpr = false; return Lexer.tokenize(value, token.position, token.next, token, Lexer.TokenType.LambdaPredicateExpression); } } exports.lambdaPredicateExpr = lambdaPredicateExpr; function anyExpr(value, index) { if (!utils_1.default.equals(value, index, 'any')) { return; } const start = index; index += 3; const open = Lexer.OPEN(value, index); if (!open) { return; } index = open; index = Lexer.BWS(value, index); const variable = lambdaVariableExpr(value, index); let predicate; if (variable) { index = variable.next; index = Lexer.BWS(value, index); const colon = Lexer.COLON(value, index); if (!colon) { return; } index = colon; index = Lexer.BWS(value, index); predicate = lambdaPredicateExpr(value, index); if (!predicate) { return; } index = predicate.next; } index = Lexer.BWS(value, index); const close = Lexer.CLOSE(value, index); if (!close) { return; } index = close; return Lexer.tokenize(value, start, index, { variable, predicate }, Lexer.TokenType.AnyExpression); } exports.anyExpr = anyExpr; function allExpr(value, index) { if (!utils_1.default.equals(value, index, 'all')) { return; } const start = index; index += 3; const open = Lexer.OPEN(value, index); if (!open) { return; } index = open; index = Lexer.BWS(value, index); const variable = lambdaVariableExpr(value, index); if (!variable) { return; } index = variable.next; index = Lexer.BWS(value, index); const colon = Lexer.COLON(value, index); if (!colon) { return; } index = colon; index = Lexer.BWS(value, index); const predicate = lambdaPredicateExpr(value, index); if (!predicate) { return; } index = predicate.next; index = Lexer.BWS(value, index); const close = Lexer.CLOSE(value, index); if (!close) { return; } index = close; return Lexer.tokenize(value, start, index, { variable, predicate }, Lexer.TokenType.AllExpression); } exports.allExpr = allExpr; function collectionNavigationExpr(value, index) { const start = index; let entity, navigation, path; if (value[index] === 0x2f) { index++; entity = NameOrIdentifier.qualifiedEntityTypeName(value, index); if (!entity) { return; } index = entity.next; } const predicate = keyPredicate(value, index); if (predicate) { index = predicate.next; navigation = singleNavigationExpr(value, index); if (navigation) { index = navigation.next; } } else { path = collectionPathExpr(value, index); if (path) { index = path.next; } } if (index > start) { return Lexer.tokenize(value, start, index, { entity, predicate, navigation, path }, Lexer.TokenType.CollectionNavigationExpression); } } exports.collectionNavigationExpr = collectionNavigationExpr; function keyPredicate(value, index, metadataContext) { return simpleKey(value, index, metadataContext) || compoundKey(value, index); } exports.keyPredicate = keyPredicate; function simpleKey(value, index, metadataContext) { const open = Lexer.OPEN(value, index); if (!open) { return; } const start = index; index = open; const token = keyPropertyValue(value, index); if (!token) { return; } const close = Lexer.CLOSE(value, token.next); if (!close) { return; } let key; if (typeof metadataContext === 'object' && metadataContext.key && metadataContext.key.propertyRefs && metadataContext.key.propertyRefs[0] && metadataContext.key.propertyRefs[0].name) { key = metadataContext.key.propertyRefs[0].name; } return Lexer.tokenize(value, start, close, { key, value: token }, Lexer.TokenType.SimpleKey); } exports.simpleKey = simpleKey; function compoundKey(value, index) { const open = Lexer.OPEN(value, index); if (!open) { return; } const start = index; index = open; let pair = keyValuePair(value, index); if (!pair) { return; } const keys = []; while (pair) { keys.push(pair); const comma = Lexer.COMMA(value, pair.next); if (comma) { pair = keyValuePair(value, comma); } else { pair = null; } } index = keys[keys.length - 1].next; const close = Lexer.CLOSE(value, index); if (!close) { return; } index = close; return Lexer.tokenize(value, start, index, keys, Lexer.TokenType.CompoundKey); } exports.compoundKey = compoundKey; function keyValuePair(value, index) { const prop = NameOrIdentifier.primitiveKeyProperty(value, index) || keyPropertyAlias(value, index); if (!prop) { return; } const eq = Lexer.EQ(value, prop.next); if (!eq) { return; } const val = keyPropertyValue(value, eq); if (val) { return Lexer.tokenize(value, index, val.next, { key: prop, value: val }, Lexer.TokenType.KeyValuePair); } } exports.keyValuePair = keyValuePair; function keyPropertyValue(value, index) { const token = PrimitiveLiteral.primitiveLiteral(value, index); if (token) { token.type = Lexer.TokenType.KeyPropertyValue; return token; } } exports.keyPropertyValue = keyPropertyValue; function keyPropertyAlias(value, index) { return NameOrIdentifier.odataIdentifier(value, index, Lexer.TokenType.KeyPropertyAlias); } exports.keyPropertyAlias = keyPropertyAlias; function singleNavigationExpr(value, index) { if (value[index] !== 0x2f) { return; } const member = memberExpr(value, index + 1); if (member) { return Lexer.tokenize(value, index, member.next, member, Lexer.TokenType.SingleNavigationExpression); } } exports.singleNavigationExpr = singleNavigationExpr; function collectionPathExpr(value, index) { let token = countExpr(value, index); if (!token) { if (value[index] === 0x2f) { token = boundFunctionExpr(value, index + 1) || anyExpr(value, index + 1) || allExpr(value, index + 1); } } if (token) { return Lexer.tokenize(value, index, token.next, token, Lexer.TokenType.CollectionPathExpression); } } exports.collectionPathExpr = collectionPathExpr; function complexPathExpr(value, index) { if (value[index] !== 0x2f) { return; } const start = index; index++; const token = NameOrIdentifier.qualifiedComplexTypeName(value, index); if (token) { if (value[token.next] !== 0x2f) { return; } index = token.next + 1; } const expr = propertyPathExpr(value, index) || boundFunctionExpr(value, index); if (expr) { return Lexer.tokenize(value, start, expr.next, token ? [token, expr] : [expr], Lexer.TokenType.ComplexPathExpression); } } exports.complexPathExpr = complexPathExpr; function singlePathExpr(value, index) { if (value[index] !== 0x2f) { return; } const boundFunction = boundFunctionExpr(value, index + 1); if (boundFunction) { return Lexer.tokenize(value, index, boundFunction.next, boundFunction, Lexer.TokenType.SinglePathExpression); } } exports.singlePathExpr = singlePathExpr; function functionExpr(value, index) { const namespaceNext = NameOrIdentifier.namespace(value, index); if (namespaceNext === index || value[namespaceNext] !== 0x2e) { return; } const start = index; index = namespaceNext + 1; const token = NameOrIdentifier.odataIdentifier(value, index); if (!token) { return; } token.position = start; token.value.namespace = utils_1.default.stringify(value, start, namespaceNext); token.raw = utils_1.default.stringify(value, start, token.next); index = token.next; const params = functionExprParameters(value, index); if (!params) { return; } index = params.next; const expr = collectionPathExpr(value, index) || collectionNavigationExpr(value, index) || singleNavigationExpr(value, index) || complexPathExpr(value, index) || singlePathExpr(value, index); if (expr) { index = expr.next; } return Lexer.tokenize(value, start, index, { fn: token, params, expression: expr }, Lexer.TokenType.FunctionExpression); } exports.functionExpr = functionExpr; function boundFunctionExpr(value, index) { return functionExpr(value, index); } exports.boundFunctionExpr = boundFunctionExpr; function functionExprParameters(value, index) { const open = Lexer.OPEN(value, index); if (!open) { return; } const start = index; index = open; const params = []; let expr = functionExprParameter(value, index); while (expr) { params.push(expr); const comma = Lexer.COMMA(value, expr.next); if (comma) { index = comma; expr = functionExprParameter(value, index); if (!expr) { return; } } else { index = expr.next; expr = null; } } const close = Lexer.CLOSE(value, index); if (!close) { return; } index = close; return Lexer.tokenize(value, start, index, params, Lexer.TokenType.FunctionExpressionParameters); } exports.functionExprParameters = functionExprParameters; function functionExprParameter(value, index) { const name = parameterName(value, index); if (!name) { return; } const eq = Lexer.EQ(value, name.next); if (!name || !eq) { return; } const start = index; index = eq; const param = parameterAlias(value, index) || parameterValue(value, index); if (!param) { return; } return Lexer.tokenize(value, start, param.next, { name, value: param }, Lexer.TokenType.FunctionExpressionParameter); } exports.functionExprParameter = functionExprParameter; function parameterName(value, index) { return NameOrIdentifier.odataIdentifier(value, index, Lexer.TokenType.ParameterName); } exports.parameterName = parameterName; function parameterAlias(value, index) { const at = Lexer.AT(value, index); if (!at) { return; } const id = NameOrIdentifier.odataIdentifier(value, at); if (id) { return Lexer.tokenize(value, index, id.next, id.value, Lexer.TokenType.ParameterAlias); } } exports.parameterAlias = parameterAlias; function parameterValue(value, index) { const token = ArrayOrObject.arrayOrObject(value, index) || commonExpr(value, index); if (token) { return Lexer.tokenize(value, index, token.next, token.value, Lexer.TokenType.ParameterValue); } } exports.parameterValue = parameterValue; function countExpr(value, index) { if (utils_1.default.equals(value, index, '/$count')) { return Lexer.tokenize(value, index, index + 7, '/$count', Lexer.TokenType.CountExpression); } } exports.countExpr = countExpr; function refExpr(value, index) { if (utils_1.default.equals(value, index, '/$ref')) { return Lexer.tokenize(value, index, index + 5, '/$ref', Lexer.TokenType.RefExpression); } } exports.refExpr = refExpr; function valueExpr(value, index) { if (utils_1.default.equals(value, index, '/$value')) { return Lexer.tokenize(value, index, index + 7, '/$value', Lexer.TokenType.ValueExpression); } } exports.valueExpr = valueExpr; function rootExpr(value, index) { if (!utils_1.default.equals(value, index, '$root/')) { return; } const start = index; index += 6; const entitySet = NameOrIdentifier.entitySetName(value, index); let predicate, entity, token; if (entitySet) { predicate = keyPredicate(value, entitySet.next); } if (!(entitySet && predicate)) { entity = NameOrIdentifier.singletonEntity(value, index); if (!entity) { return; } token = { entity }; } else { token = { entitySet, keys: predicate }; } index = (predicate || entity).next; const nav = singleNavigationExpr(value, index); if (nav) { index = nav.next; } return Lexer.tokenize(value, start, index, { current: token, next: nav }, Lexer.TokenType.RootExpression); } exports.rootExpr = rootExpr; //# sourceMappingURL=expressions.js.map