@odata/parser
Version:
OData(V4) Parser
514 lines • 20.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.all = exports.crossjoin = exports.functionParameter = exports.functionParameters = exports.functionImportCall = exports.actionImportCall = exports.boundPrimitiveColFuncCall = exports.boundPrimitiveFuncCall = exports.boundComplexColFuncCall = exports.boundComplexFuncCall = exports.boundEntityColFuncCall = exports.boundEntityFuncCall = exports.boundFunctionCall = exports.boundActionCall = exports.boundOperation = exports.complexPath = exports.singlePath = exports.collectionPath = exports.propertyPath = exports.singleNavigation = exports.collectionNavigationPath = exports.collectionNavigation = exports.metadata = exports.entity = exports.batch = exports.resourcePath = void 0;
const Expressions = require("./expressions");
const Lexer = require("./lexer");
const NameOrIdentifier = require("./nameOrIdentifier");
const PrimitiveLiteral = require("./primitiveLiteral");
const utils_1 = require("./utils");
function resourcePath(value, index, metadataContext) {
if (value[index] === 0x2f) {
index++;
}
const token = batch(value, index) ||
entity(value, index, metadataContext) ||
metadata(value, index);
if (token) {
return token;
}
const resource = NameOrIdentifier.entitySetName(value, index, metadataContext) ||
functionImportCall(value, index, metadataContext) ||
crossjoin(value, index) ||
all(value, index) ||
actionImportCall(value, index, metadataContext) ||
NameOrIdentifier.singletonEntity(value, index);
if (!resource) {
return;
}
const start = index;
index = resource.next;
let navigation;
switch (resource.type) {
case Lexer.TokenType.EntitySetName:
navigation = collectionNavigation(value, resource.next, resource.metadata);
metadataContext = resource.metadata;
delete resource.metadata;
break;
case Lexer.TokenType.EntityCollectionFunctionImportCall:
navigation = collectionNavigation(value, resource.next, resource.value.import.metadata);
metadataContext = resource.value.import.metadata;
delete resource.value.import.metadata;
break;
case Lexer.TokenType.SingletonEntity:
navigation = singleNavigation(value, resource.next, resource.metadata);
metadataContext = resource.metadata;
delete resource.metadata;
break;
case Lexer.TokenType.EntityFunctionImportCall:
navigation = singleNavigation(value, resource.next, resource.value.import.metadata);
metadataContext = resource.value.import.metadata;
delete resource.value.import.metadata;
break;
case Lexer.TokenType.ComplexCollectionFunctionImportCall:
case Lexer.TokenType.PrimitiveCollectionFunctionImportCall:
navigation = collectionPath(value, resource.next, resource.value.import.metadata);
metadataContext = resource.value.import.metadata;
delete resource.value.import.metadata;
break;
case Lexer.TokenType.ComplexFunctionImportCall:
navigation = complexPath(value, resource.next, resource.value.import.metadata);
metadataContext = resource.value.import.metadata;
delete resource.value.import.metadata;
break;
case Lexer.TokenType.PrimitiveFunctionImportCall:
navigation = singlePath(value, resource.next, resource.value.import.metadata);
metadataContext = resource.value.import.metadata;
delete resource.value.import.metadata;
break;
}
if (navigation) {
index = navigation.next;
}
if (value[index] === 0x2f) {
index++;
}
if (resource) {
return Lexer.tokenize(value, start, index, { resource, navigation }, Lexer.TokenType.ResourcePath, navigation || { metadata: metadataContext });
}
}
exports.resourcePath = resourcePath;
function batch(value, index) {
if (utils_1.default.equals(value, index, '$batch')) {
return Lexer.tokenize(value, index, index + 6, '$batch', Lexer.TokenType.Batch);
}
}
exports.batch = batch;
function entity(value, index, metadataContext) {
if (utils_1.default.equals(value, index, '$entity')) {
const start = index;
index += 7;
let name;
if (value[index] === 0x2f) {
name = NameOrIdentifier.qualifiedEntityTypeName(value, index + 1, metadataContext);
if (!name) {
return;
}
index = name.next;
}
return Lexer.tokenize(value, start, index, name || '$entity', Lexer.TokenType.Entity);
}
}
exports.entity = entity;
function metadata(value, index) {
if (utils_1.default.equals(value, index, '$metadata')) {
return Lexer.tokenize(value, index, index + 9, '$metadata', Lexer.TokenType.Metadata);
}
}
exports.metadata = metadata;
function collectionNavigation(value, index, metadataContext) {
const start = index;
let name;
if (value[index] === 0x2f) {
name = NameOrIdentifier.qualifiedEntityTypeName(value, index + 1, metadataContext);
if (name) {
index = name.next;
metadataContext = name.value.metadata;
delete name.value.metadata;
}
}
const path = collectionNavigationPath(value, index, metadataContext);
if (path) {
index = path.next;
}
if (!name && !path) {
return;
}
return Lexer.tokenize(value, start, index, { name, path }, Lexer.TokenType.CollectionNavigation, path || name);
}
exports.collectionNavigation = collectionNavigation;
function collectionNavigationPath(value, index, metadataContext) {
const start = index;
const token = collectionPath(value, index, metadataContext) ||
Expressions.refExpr(value, index);
if (token) {
return token;
}
const predicate = Expressions.keyPredicate(value, index, metadataContext);
if (predicate) {
let tokenValue = { predicate };
index = predicate.next;
const navigation = singleNavigation(value, index, metadataContext);
if (navigation) {
tokenValue = { predicate, navigation };
index = navigation.next;
}
return Lexer.tokenize(value, start, index, tokenValue, Lexer.TokenType.CollectionNavigationPath, navigation || { metadata: metadataContext });
}
}
exports.collectionNavigationPath = collectionNavigationPath;
function singleNavigation(value, index, metadataContext) {
let token = boundOperation(value, index, false, metadataContext) ||
Expressions.refExpr(value, index) ||
Expressions.valueExpr(value, index);
if (token) {
return token;
}
const start = index;
let name;
if (value[index] === 0x2f) {
name = NameOrIdentifier.qualifiedEntityTypeName(value, index + 1, metadataContext);
if (name) {
index = name.next;
metadataContext = name.value.metadata;
delete name.value.metadata;
}
}
if (value[index] === 0x2f) {
token = propertyPath(value, index + 1, metadataContext);
if (token) {
index = token.next;
}
}
if (!name && !token) {
return;
}
return Lexer.tokenize(value, start, index, { name, path: token }, Lexer.TokenType.SingleNavigation, token);
}
exports.singleNavigation = singleNavigation;
function propertyPath(value, index, metadataContext) {
const token = NameOrIdentifier.entityColNavigationProperty(value, index, metadataContext) ||
NameOrIdentifier.entityNavigationProperty(value, index, metadataContext) ||
NameOrIdentifier.complexColProperty(value, index, metadataContext) ||
NameOrIdentifier.complexProperty(value, index, metadataContext) ||
NameOrIdentifier.primitiveColProperty(value, index, metadataContext) ||
NameOrIdentifier.primitiveProperty(value, index, metadataContext) ||
NameOrIdentifier.streamProperty(value, index, metadataContext);
if (!token) {
return;
}
const start = index;
index = token.next;
let navigation;
switch (token.type) {
case Lexer.TokenType.EntityCollectionNavigationProperty:
navigation = collectionNavigation(value, index, token.metadata);
delete token.metadata;
break;
case Lexer.TokenType.EntityNavigationProperty:
navigation = singleNavigation(value, index, token.metadata);
delete token.metadata;
break;
case Lexer.TokenType.ComplexCollectionProperty:
navigation = collectionPath(value, index, token.metadata);
delete token.metadata;
break;
case Lexer.TokenType.ComplexProperty:
navigation = complexPath(value, index, token.metadata);
delete token.metadata;
break;
case Lexer.TokenType.PrimitiveCollectionProperty:
navigation = collectionPath(value, index, token.metadata);
delete token.metadata;
break;
case Lexer.TokenType.PrimitiveKeyProperty:
case Lexer.TokenType.PrimitiveProperty:
navigation = singlePath(value, index, token.metadata);
delete token.metadata;
break;
case Lexer.TokenType.StreamProperty:
navigation = boundOperation(value, index, token.metadata);
delete token.metadata;
break;
}
if (navigation) {
index = navigation.next;
}
return Lexer.tokenize(value, start, index, { path: token, navigation }, Lexer.TokenType.PropertyPath, navigation);
}
exports.propertyPath = propertyPath;
function collectionPath(value, index, metadataContext) {
return (Expressions.countExpr(value, index) ||
boundOperation(value, index, true, metadataContext));
}
exports.collectionPath = collectionPath;
function singlePath(value, index, metadataContext) {
return (Expressions.valueExpr(value, index) ||
boundOperation(value, index, false, metadataContext));
}
exports.singlePath = singlePath;
function complexPath(value, index, metadataContext) {
const start = index;
let name, token;
if (value[index] === 0x2f) {
name = NameOrIdentifier.qualifiedComplexTypeName(value, index + 1, metadataContext);
if (name) {
index = name.next;
}
}
if (value[index] === 0x2f) {
token = propertyPath(value, index + 1, metadataContext);
if (!token) {
return;
}
index = token.next;
}
else {
token = boundOperation(value, index, false, metadataContext);
}
if (!name && !token) {
return;
}
return Lexer.tokenize(value, start, index, { name, path: token }, Lexer.TokenType.ComplexPath, token);
}
exports.complexPath = complexPath;
function boundOperation(value, index, isCollection, metadataContext) {
if (value[index] !== 0x2f) {
return;
}
const start = index;
index++;
const operation = boundEntityColFuncCall(value, index, isCollection, metadataContext) ||
boundEntityFuncCall(value, index, isCollection, metadataContext) ||
boundComplexColFuncCall(value, index, isCollection, metadataContext) ||
boundComplexFuncCall(value, index, isCollection, metadataContext) ||
boundPrimitiveColFuncCall(value, index, isCollection, metadataContext) ||
boundPrimitiveFuncCall(value, index, isCollection, metadataContext) ||
boundActionCall(value, index, isCollection, metadataContext);
if (!operation) {
return;
}
index = operation.next;
let name, navigation;
switch (operation.type) {
case Lexer.TokenType.BoundActionCall:
break;
case Lexer.TokenType.BoundEntityCollectionFunctionCall:
navigation = collectionNavigation(value, index, operation.value.call.metadata);
delete operation.metadata;
break;
case Lexer.TokenType.BoundEntityFunctionCall:
navigation = singleNavigation(value, index, operation.value.call.metadata);
delete operation.metadata;
break;
case Lexer.TokenType.BoundComplexCollectionFunctionCall:
if (value[index] === 0x2f) {
name = NameOrIdentifier.qualifiedComplexTypeName(value, index + 1, operation.value.call.metadata);
if (name) {
index = name.next;
}
}
navigation = collectionPath(value, index, operation.value.call.metadata);
delete operation.metadata;
break;
case Lexer.TokenType.BoundComplexFunctionCall:
navigation = complexPath(value, index, operation.value.call.metadata);
delete operation.metadata;
break;
case Lexer.TokenType.BoundPrimitiveCollectionFunctionCall:
navigation = collectionPath(value, index, operation.value.call.metadata);
delete operation.metadata;
break;
case Lexer.TokenType.BoundPrimitiveFunctionCall:
navigation = singlePath(value, index, operation.value.call.metadata);
delete operation.metadata;
break;
}
if (navigation) {
index = navigation.next;
}
return Lexer.tokenize(value, start, index, { operation, name, navigation }, Lexer.TokenType.BoundOperation, navigation);
}
exports.boundOperation = boundOperation;
function boundActionCall(value, index, isCollection, metadataContext) {
const namespaceNext = NameOrIdentifier.namespace(value, index);
if (namespaceNext === index) {
return;
}
const start = index;
index = namespaceNext;
if (value[index] !== 0x2e) {
return;
}
index++;
const action = NameOrIdentifier.action(value, index, isCollection, metadataContext);
if (!action) {
return;
}
action.value.namespace = utils_1.default.stringify(value, start, namespaceNext);
return Lexer.tokenize(value, start, action.next, action, Lexer.TokenType.BoundActionCall, action);
}
exports.boundActionCall = boundActionCall;
function boundFunctionCall(value, index, odataFunction, tokenType, isCollection, metadataContext) {
const namespaceNext = NameOrIdentifier.namespace(value, index);
if (namespaceNext === index) {
return;
}
const start = index;
index = namespaceNext;
if (value[index] !== 0x2e) {
return;
}
index++;
const call = odataFunction(value, index, isCollection, metadataContext);
if (!call) {
return;
}
call.value.namespace = utils_1.default.stringify(value, start, namespaceNext);
index = call.next;
const params = functionParameters(value, index);
if (!params) {
return;
}
index = params.next;
return Lexer.tokenize(value, start, index, { call, params }, tokenType, call);
}
exports.boundFunctionCall = boundFunctionCall;
function boundEntityFuncCall(value, index, isCollection, metadataContext) {
return boundFunctionCall(value, index, NameOrIdentifier.entityFunction, Lexer.TokenType.BoundEntityFunctionCall, isCollection, metadataContext);
}
exports.boundEntityFuncCall = boundEntityFuncCall;
function boundEntityColFuncCall(value, index, isCollection, metadataContext) {
return boundFunctionCall(value, index, NameOrIdentifier.entityColFunction, Lexer.TokenType.BoundEntityCollectionFunctionCall, isCollection, metadataContext);
}
exports.boundEntityColFuncCall = boundEntityColFuncCall;
function boundComplexFuncCall(value, index, isCollection, metadataContext) {
return boundFunctionCall(value, index, NameOrIdentifier.complexFunction, Lexer.TokenType.BoundComplexFunctionCall, isCollection, metadataContext);
}
exports.boundComplexFuncCall = boundComplexFuncCall;
function boundComplexColFuncCall(value, index, isCollection, metadataContext) {
return boundFunctionCall(value, index, NameOrIdentifier.complexColFunction, Lexer.TokenType.BoundComplexCollectionFunctionCall, isCollection, metadataContext);
}
exports.boundComplexColFuncCall = boundComplexColFuncCall;
function boundPrimitiveFuncCall(value, index, isCollection, metadataContext) {
return boundFunctionCall(value, index, NameOrIdentifier.primitiveFunction, Lexer.TokenType.BoundPrimitiveFunctionCall, isCollection, metadataContext);
}
exports.boundPrimitiveFuncCall = boundPrimitiveFuncCall;
function boundPrimitiveColFuncCall(value, index, isCollection, metadataContext) {
return boundFunctionCall(value, index, NameOrIdentifier.primitiveColFunction, Lexer.TokenType.BoundPrimitiveCollectionFunctionCall, isCollection, metadataContext);
}
exports.boundPrimitiveColFuncCall = boundPrimitiveColFuncCall;
function actionImportCall(value, index, metadataContext) {
const action = NameOrIdentifier.actionImport(value, index, metadataContext);
if (action) {
return Lexer.tokenize(value, index, action.next, action, Lexer.TokenType.ActionImportCall, action);
}
}
exports.actionImportCall = actionImportCall;
function functionImportCall(value, index, metadataContext) {
const fnImport = NameOrIdentifier.entityFunctionImport(value, index, metadataContext) ||
NameOrIdentifier.entityColFunctionImport(value, index, metadataContext) ||
NameOrIdentifier.complexFunctionImport(value, index, metadataContext) ||
NameOrIdentifier.complexColFunctionImport(value, index, metadataContext) ||
NameOrIdentifier.primitiveFunctionImport(value, index, metadataContext) ||
NameOrIdentifier.primitiveColFunctionImport(value, index, metadataContext);
if (!fnImport) {
return;
}
const start = index;
index = fnImport.next;
const params = functionParameters(value, index);
if (!params) {
return;
}
index = params.next;
return Lexer.tokenize(value, start, index, { import: fnImport, params: params.value }, `${fnImport.type}Call`, fnImport);
}
exports.functionImportCall = functionImportCall;
function functionParameters(value, index, metadataContext) {
const open = Lexer.OPEN(value, index);
if (!open) {
return;
}
const start = index;
index = open;
const params = [];
let token = functionParameter(value, index);
while (token) {
params.push(token);
index = token.next;
const comma = Lexer.COMMA(value, index);
if (comma) {
index = comma;
token = functionParameter(value, index);
if (!token) {
return;
}
}
else {
break;
}
}
const close = Lexer.CLOSE(value, index);
if (!close) {
return;
}
index = close;
return Lexer.tokenize(value, start, index, params, Lexer.TokenType.FunctionParameters);
}
exports.functionParameters = functionParameters;
function functionParameter(value, index, metadataContext) {
const name = Expressions.parameterName(value, index);
if (!name) {
return;
}
const start = index;
index = name.next;
const eq = Lexer.EQ(value, index);
if (!eq) {
return;
}
index = eq;
const token = Expressions.parameterAlias(value, index) ||
PrimitiveLiteral.primitiveLiteral(value, index);
if (!token) {
return;
}
index = token.next;
return Lexer.tokenize(value, start, index, { name, value: token }, Lexer.TokenType.FunctionParameter);
}
exports.functionParameter = functionParameter;
function crossjoin(value, index, metadataContext) {
if (!utils_1.default.equals(value, index, '$crossjoin')) {
return;
}
const start = index;
index += 10;
const open = Lexer.OPEN(value, index);
if (!open) {
return;
}
index = open;
const names = [];
let token = NameOrIdentifier.entitySetName(value, index, metadataContext);
if (!token) {
return;
}
while (token) {
names.push(token);
index = token.next;
const comma = Lexer.COMMA(value, index);
if (comma) {
index = comma;
token = NameOrIdentifier.entitySetName(value, index, metadataContext);
if (!token) {
return;
}
}
else {
break;
}
}
const close = Lexer.CLOSE(value, index);
if (!close) {
return;
}
return Lexer.tokenize(value, start, index, { names }, Lexer.TokenType.Crossjoin);
}
exports.crossjoin = crossjoin;
function all(value, index) {
if (utils_1.default.equals(value, index, '$all')) {
return Lexer.tokenize(value, index, index + 4, '$all', Lexer.TokenType.AllResource);
}
}
exports.all = all;
//# sourceMappingURL=resourcePath.js.map