public FlagSetInputEvaluator(InputValueDef inputDef, TypeRef resultTypeRef, RequestObjectBase anchor, InputValueEvaluator[] valueEvals) : base(inputDef, resultTypeRef, anchor) { ElemEvaluators = valueEvals; EnumTypeDef = (EnumTypeDef)ResultTypeRef.TypeDef; }
private IList <InputValueDef> BuildArgDefs(IList <ParameterInfo> parameters, MethodBase method) { var argDefs = new List <InputValueDef>(); foreach (var prm in parameters) { var attrs = GetAllAttributes(prm, method); var prmTypeRef = GetTypeRef(prm.ParameterType, prm, $"Method {method.Name}, parameter {prm.Name}", method); if (prmTypeRef == null) { continue; } if (prmTypeRef.IsList && !prmTypeRef.TypeDef.IsEnumFlagArray()) { VerifyListParameterType(prm.ParameterType, method, prm.Name); } var dftValue = prm.DefaultValue == DBNull.Value ? null : prm.DefaultValue; var argDef = new InputValueDef() { Name = GetGraphQLName(prm), TypeRef = prmTypeRef, Attributes = attrs, ParamType = prm.ParameterType, HasDefaultValue = prm.HasDefaultValue, DefaultValue = dftValue }; argDef.Directives = BuildDirectivesFromAttributes(prm, DirectiveLocation.ArgumentDefinition, argDef); argDefs.Add(argDef); } return(argDefs); }
private InputValueEvaluator GetInputListEvaluator(InputValueDef inputDef, ValueSource valueSource, TypeRef listTypeRef) { if (valueSource.IsConstNull()) { if (listTypeRef.IsNotNull) { throw new InvalidInputException("Input type '{valueTypeRef.Name}' is not-null type, but null was encountered.", valueSource); } } if (!(valueSource is ListValueSource arrValue)) { throw new InvalidInputException($"Input type '{listTypeRef.Name}' is not list or array, expected array.", valueSource); } var elemTypeRef = listTypeRef.GetListElementTypeRef(); if (elemTypeRef == null) { throw new InvalidInputException($"Invalid input value for type {listTypeRef.Name}, expected list", valueSource); } var elemEvalList = arrValue.Values.Select(v => GetInputValueEvaluator(inputDef, v, elemTypeRef)).ToArray(); // it can be regular array or enum flag set (which is special) if (elemTypeRef.TypeDef.IsEnumFlagArray()) { return(new FlagSetInputEvaluator(inputDef, listTypeRef, valueSource, elemEvalList)); } else { return(new InputListEvaluator(inputDef, listTypeRef, valueSource, elemEvalList)); } }
private IList <InputValueDef> BuildArgDefs(IList <ParameterInfo> parameters, MethodBase method) { var argDefs = new List <InputValueDef>(); foreach (var prm in parameters) { var attrs = GetAllAttributesAndAdjustments(prm, method); var prmTypeRef = GetMemberGraphQLTypeRef(prm.ParameterType, prm, $"Method {method.Name}, parameter {prm.Name}", method); if (prmTypeRef == null) { continue; } if (prmTypeRef.IsList && !prmTypeRef.TypeDef.IsEnumFlagArray()) { VerifyListParameterType(prm.ParameterType, method, prm.Name); } var dftValue = prm.DefaultValue == DBNull.Value ? null : prm.DefaultValue; // special case: if default value is null, it is nullable if (prm.HasDefaultValue && dftValue == null && prmTypeRef.Kind == TypeKind.NonNull) { prmTypeRef = prmTypeRef.Inner; // nullable } var argDef = new InputValueDef() { Name = GetGraphQLName(prm), TypeRef = prmTypeRef, Attributes = attrs, ParamType = prm.ParameterType, HasDefaultValue = prm.HasDefaultValue, DefaultValue = dftValue }; argDef.Directives = BuildDirectivesFromAttributes(prm, DirectiveLocation.ArgumentDefinition); argDefs.Add(argDef); } return(argDefs); }
private ConstInputValue CreateConstantInputValue(InputValueDef inputDef, RequestObjectBase anchor, TypeRef resultTypeRef, object value) { // We convert const value upfront to target typeRef var convValue = _requestContext.ValidateConvert(value, resultTypeRef, anchor); var constEval = new ConstInputValue(inputDef, resultTypeRef, anchor, convValue); return(constEval); }
private InputValueEvaluator GetInputValueEvaluatorImpl(InputValueDef inputDef, ValueSource valueSource, TypeRef resultTypeRef) { if (valueSource is VariableValueSource vref) { return(GetVariableRefEvaluator(inputDef, resultTypeRef, vref)); } if (resultTypeRef.IsList) { return(GetInputListEvaluator(inputDef, valueSource, resultTypeRef)); } switch (resultTypeRef.TypeDef) { case ScalarTypeDef stdef: if (valueSource is TokenValueSource tknIv) { var constValue = stdef.Scalar.ParseToken(_requestContext, tknIv.TokenData); return(CreateConstantInputValue(inputDef, valueSource, resultTypeRef, constValue)); } else { throw new InvalidInputException("invalid input value, expected scalar", valueSource); } case EnumTypeDef etdef: if (etdef.IsFlagSet && valueSource is ListValueSource) { return(GetInputListEvaluator(inputDef, valueSource, resultTypeRef)); } if (valueSource is TokenValueSource tknValueSrc) { if (tknValueSrc.TokenData.TermName != TermNames.Name) { throw new InvalidInputException($"Invalid value '{tknValueSrc.TokenData.Text}', expected Enum value.", valueSource); } var vname = tknValueSrc.TokenData.Text; var enumVal = etdef.EnumValues.FirstOrDefault(ev => ev.Name == vname); if (enumVal == null) { throw new InvalidInputException($"Invalid value '{vname}' for enum '{etdef.ClrType.Name}'.", valueSource); } return(CreateConstantInputValue(inputDef, tknValueSrc, resultTypeRef, enumVal.ClrValue)); } else { throw new InvalidInputException($"Invalid input value, expected enum value.", valueSource); } case InputObjectTypeDef inpObjDef: return(GetInputObjectEvaluator(inputDef, valueSource, resultTypeRef)); default: return(null); //never happens } }
public InputValueEvaluator(InputValueDef inputDef, TypeRef resultTypeRef, RequestObjectBase anchor) { InputDef = inputDef; ResultTypeRef = resultTypeRef; Anchor = anchor; // prepare directives if (inputDef.Directives != null) { Directives = inputDef.Directives.Where(d => d.Def.Handler is IInputValueDirectiveAction) .Select(d => new RuntimeModelDirective(d)).ToList(); } }
public InputListEvaluator(InputValueDef inputDef, TypeRef resultTypeRef, RequestObjectBase anchor, InputValueEvaluator[] elemEvaluators) : base(inputDef, resultTypeRef, anchor) { ElemEvaluators = elemEvaluators; if (ResultTypeRef.Kind == TypeKind.NonNull) { ElemTypeRef = ResultTypeRef.Inner.Inner; } else { ElemTypeRef = ResultTypeRef.Inner; } }
} //method private string FormatArg(InputValueDef argDef, object value) { string strV; if (value == null) { strV = "null"; } else { strV = argDef.TypeRef.TypeDef.ToSchemaDocString(value); } return($"{argDef.Name}: {strV}"); }
private IList <VariableDef> BuildOperationVariables(Node varDefsNode) { if (varDefsNode == null) { return(VariableDef.EmptyList); } var varList = new List <VariableDef>(); foreach (var vn in varDefsNode.ChildNodes) { var name = vn.ChildNodes[0].GetText(); // remove $ prefix; we define/track var name as a token without $; in Http/Json request variables are referenced without prefix; // see https://graphql.org/learn/serving-over-http/#post-request name = name.Substring(1); var typeRef = BuildTypeReference(vn.ChildNodes[1]); if (typeRef == null) { continue; // error already posted } var typeDef = typeRef.TypeDef; if (!_allowedVarTypeKinds.Contains(typeDef.Kind)) { AddError($"Invalid variable type ( {name}: {typeRef.Name}). Only scalar, enum or input types are allowed.", vn); continue; } var inpDef = new InputValueDef() { Name = name, TypeRef = typeRef }; var varDef = new VariableDef() { Name = name, InputDef = inpDef, SourceLocation = vn.GetLocation() }; // check default value if (vn.ChildNodes.Count > 2) { varDef.ParsedDefaultValue = BuildInputValue(vn.ChildNodes[2], varDef); } // directives var dirListNode = vn.FindChild(TermNames.DirListOpt); if (dirListNode != null) { varDef.DirectiveRefs = BuildDirectives(dirListNode, DirectiveLocation.VariableDefinition, varDef); } varList.Add(varDef); } return(varList); }
private VariableRefEvaluator GetVariableRefEvaluator(InputValueDef inputDef, TypeRef resultTypeRef, VariableValueSource varRef) { var varDecl = _currentOp.Variables.FirstOrDefault(vd => vd.Name == varRef.VariableName); if (varDecl == null) { throw new InvalidInputException($"Variable ${varRef.VariableName} not defined.", varRef); } // check type compatibility if (!resultTypeRef.IsConvertibleFrom(varDecl.InputDef.TypeRef)) { throw new InvalidInputException( $"Incompatible types: variable ${varRef.VariableName} cannot be converted to type '{resultTypeRef.Name}'", varRef); } return(new VariableRefEvaluator(inputDef, varDecl)); }
internal InputValueEvaluator GetInputValueEvaluator(InputValueDef inputDef, ValueSource valueSource, TypeRef valueTypeRef) { if (valueSource.IsConstNull()) { return(CreateConstantInputValue(inputDef, valueSource, valueTypeRef, null)); } var eval = GetInputValueEvaluatorImpl(inputDef, valueSource, valueTypeRef); // replace with constant if it does not depend on vars if (eval.IsConst()) { var value = eval.GetValue(_requestContext); eval = CreateConstantInputValue(inputDef, valueSource, valueTypeRef, value); } return(eval); }
private IList <VariableDef> BuildOperationVariables(Node varDefsNode) { if (varDefsNode == null) { return(VariableDef.EmptyList); } var varList = new List <VariableDef>(); foreach (var vn in varDefsNode.ChildNodes) { var name = vn.ChildNodes[0].ChildNodes[1].Token.Text; var typeRef = BuildTypeReference(vn.ChildNodes[1]); if (typeRef == null) { continue; // error already posted } var typeDef = typeRef.TypeDef; if (!_allowedVarTypeKinds.Contains(typeDef.Kind)) { AddError($"Invalid variable type ( {name}: {typeRef.Name}). Only scalar, enum or input types are allowed.", vn); continue; } var inpDef = new InputValueDef() { Name = name, TypeRef = typeRef }; var varDef = new VariableDef() { Name = name, InputDef = inpDef, SourceLocation = vn.GetLocation() }; // check default value if (vn.ChildNodes.Count > 2) { varDef.ParsedDefaultValue = BuildInputValue(vn.ChildNodes[2], varDef); } // directives var dirListNode = vn.FindChild(TermNames.DirListOpt); if (dirListNode != null) { varDef.DirectiveRefs = BuildDirectives(dirListNode, DirectiveLocation.VariableDefinition, varDef); } varList.Add(varDef); } return(varList); }
private void Append(InputValueDef valueDef, bool indent = false) { AppendDescr(valueDef.Description, true); if (indent) { _builder.Append(Indent); } _builder.Append(valueDef.Name); _builder.Append(": "); _builder.Append(valueDef.TypeRef.Name); if (valueDef.HasDefaultValue) { _builder.Append(" = "); var tdef = valueDef.TypeRef.TypeDef; _builder.Append(tdef.ToSchemaDocString(valueDef.DefaultValue)); } AppendDirs(valueDef); }
private void BuildInputObjectFields(InputObjectTypeDef inpTypeDef) { var members = inpTypeDef.ClrType.GetFieldsProps(); foreach (var member in members) { var attrs = GetAllAttributes(member); var mtype = member.GetMemberReturnType(); var typeRef = GetTypeRef(mtype, member, $"Field {inpTypeDef.Name}.{member.Name}"); if (typeRef == null) { return; // error found, it is already logged } if (typeRef.IsList && !typeRef.TypeDef.IsEnumFlagArray()) { // list members must be IList<T> or T[] - this is important, lists are instantiated as arrays when deserializing if (!mtype.IsArray && !mtype.IsInterface) { AddError($"Input type member {inpTypeDef.Name}.{member.Name}: list must be either array or IList<T>."); continue; } } switch (typeRef.TypeDef.Kind) { case TypeKind.Scalar: case TypeKind.Enum: case TypeKind.InputObject: break; default: AddError($"Input type member {inpTypeDef.Name}.{member.Name}: type {mtype} is not scalar or input type."); continue; } var inpFldDef = new InputValueDef() { Name = member.Name.FirstLower(), TypeRef = typeRef, Attributes = attrs, InputObjectClrMember = member, Description = _docLoader.GetDocString(member, member.DeclaringType) }; inpFldDef.Directives = BuildDirectivesFromAttributes(member, DirectiveLocation.InputFieldDefinition, inpFldDef); inpTypeDef.Fields.Add(inpFldDef); } //foreach }
private InputObjectEvaluator GetInputObjectEvaluator(InputValueDef inputDef, ValueSource valueSource, TypeRef typeRef) { var inpObjTypeDef = (InputObjectTypeDef)typeRef.TypeDef; // valueSource is not null (its value), we already checked it before coming here if (!(valueSource is ObjectValueSource parsedInputObj)) { throw new InvalidInputException($"Value is not InputObject, expected value of type '{typeRef.Name}'.", valueSource); } var fields = new List <InputFieldEvalInfo>(); foreach (var fldDef in inpObjTypeDef.Fields) { InputValueEvaluator fldEval; if (parsedInputObj.Fields.TryGetValue(fldDef.Name, out var inpValue)) { fldEval = GetInputValueEvaluator(fldDef, inpValue, fldDef.TypeRef); } else if (fldDef.HasDefaultValue) { fldEval = CreateConstantInputValue(fldDef, valueSource, typeRef, fldDef.DefaultValue); } else if (!fldDef.TypeRef.IsNotNull) { fldEval = CreateConstantInputValue(fldDef, valueSource, typeRef, null); } else { throw new InvalidInputException($"Missing value for field '{fldDef.Name}'.", valueSource); } fields.Add(new InputFieldEvalInfo() { FieldDef = fldDef, ValueEvaluator = fldEval }); // TODO: add check that there are no 'extra' members in parsed object } var result = new InputObjectEvaluator(inputDef, typeRef, valueSource, fields); return(result); }
public InputValueEvaluator(InputValueDef inputDef, TypeRef resultTypeRef, RequestObjectBase anchor) { InputDef = inputDef; ResultTypeRef = resultTypeRef; Anchor = anchor; }
public VariableRefEvaluator(InputValueDef inputDef, VariableDef varDecl) : base(inputDef, varDecl.InputDef.TypeRef, varDecl) { Variable = varDecl; }
public ConstInputValue(InputValueDef inputDef, TypeRef resultTypeRef, RequestObjectBase anchor, object value) : base(inputDef, resultTypeRef, anchor) { Value = value; }
public InputObjectEvaluator(InputValueDef inputDef, TypeRef resultTypeRef, RequestObjectBase anchor, IList <InputFieldEvalInfo> fields) : base(inputDef, resultTypeRef, anchor) { Fields = fields; }