private static bool ParseSegment(TemplateParserContext context, List<TemplateSegment> segments) { Debug.Assert(context != null); Debug.Assert(segments != null); var segment = new TemplateSegment(); while (true) { if (context.Current == OpenBrace) { if (!context.Next()) { // This is a dangling open-brace, which is not allowed context.Error = Resources.TemplateRoute_MismatchedParameter; return false; } if (context.Current == OpenBrace) { // This is an 'escaped' brace in a literal, like "{{foo" context.Back(); if (!ParseLiteral(context, segment)) { return false; } } else { // This is the inside of a parameter if (!ParseParameter(context, segment)) { return false; } } } else if (context.Current == Separator) { // We've reached the end of the segment break; } else { if (!ParseLiteral(context, segment)) { return false; } } if (!context.Next()) { // We've reached the end of the string break; } } if (IsSegmentValid(context, segment)) { segments.Add(segment); return true; } else { return false; } }
private static bool ParseParameter(TemplateParserContext context, TemplateSegment segment) { context.Mark(); while (true) { if (context.Current == OpenBrace) { // This is an open brace inside of a parameter, it has to be escaped if (context.Next()) { if (context.Current != OpenBrace) { // If we see something like "{p1:regex(^\d{3", we will come here. context.Error = Resources.TemplateRoute_UnescapedBrace; return false; } } else { // This is a dangling open-brace, which is not allowed // Example: "{p1:regex(^\d{" context.Error = Resources.TemplateRoute_MismatchedParameter; return false; } } else if (context.Current == CloseBrace) { // When we encounter Closed brace here, it either means end of the parameter or it is a closed // brace in the parameter, in that case it needs to be escaped. // Example: {p1:regex(([}}])\w+}. First pair is escaped one and last marks end of the parameter if (!context.Next()) { // This is the end of the string -and we have a valid parameter context.Back(); break; } if (context.Current == CloseBrace) { // This is an 'escaped' brace in a parameter name } else { // This is the end of the parameter context.Back(); break; } } if (!context.Next()) { // This is a dangling open-brace, which is not allowed context.Error = Resources.TemplateRoute_MismatchedParameter; return false; } } var rawParameter = context.Capture(); var decoded = rawParameter.Replace("}}", "}").Replace("{{", "{"); // At this point, we need to parse the raw name for inline constraint, // default values and optional parameters. var templatePart = InlineRouteParameterParser.ParseRouteParameter(decoded); if (templatePart.IsCatchAll && templatePart.IsOptional) { context.Error = Resources.TemplateRoute_CatchAllCannotBeOptional; return false; } if (templatePart.IsOptional && templatePart.DefaultValue != null) { // Cannot be optional and have a default value. // The only way to declare an optional parameter is to have a ? at the end, // hence we cannot have both default value and optional parameter within the template. // A workaround is to add it as a separate entry in the defaults argument. context.Error = Resources.TemplateRoute_OptionalCannotHaveDefaultValue; return false; } var parameterName = templatePart.Name; if (IsValidParameterName(context, parameterName)) { segment.Parts.Add(templatePart); return true; } else { return false; } }
private static bool ParseLiteral(TemplateParserContext context, TemplateSegment segment) { context.Mark(); string encoded; while (true) { if (context.Current == Separator) { encoded = context.Capture(); context.Back(); break; } else if (context.Current == OpenBrace) { if (!context.Next()) { // This is a dangling open-brace, which is not allowed context.Error = Resources.TemplateRoute_MismatchedParameter; return false; } if (context.Current == OpenBrace) { // This is an 'escaped' brace in a literal, like "{{foo" - keep going. } else { // We've just seen the start of a parameter, so back up and return context.Back(); encoded = context.Capture(); context.Back(); break; } } else if (context.Current == CloseBrace) { if (!context.Next()) { // This is a dangling close-brace, which is not allowed context.Error = Resources.TemplateRoute_MismatchedParameter; return false; } if (context.Current == CloseBrace) { // This is an 'escaped' brace in a literal, like "{{foo" - keep going. } else { // This is an unbalanced close-brace, which is not allowed context.Error = Resources.TemplateRoute_MismatchedParameter; return false; } } if (!context.Next()) { encoded = context.Capture(); break; } } var decoded = encoded.Replace("}}", "}").Replace("{{", "{"); if (IsValidLiteral(context, decoded)) { segment.Parts.Add(TemplatePart.CreateLiteral(decoded)); return true; } else { return false; } }
private static bool ParseSegment(TemplateParserContext context, List <TemplateSegment> segments) { Debug.Assert(context != null); Debug.Assert(segments != null); var segment = new TemplateSegment(); while (true) { if (context.Current == OpenBrace) { if (!context.Next()) { // This is a dangling open-brace, which is not allowed context.Error = Resources.TemplateRoute_MismatchedParameter; return(false); } if (context.Current == OpenBrace) { // This is an 'escaped' brace in a literal, like "{{foo" context.Back(); if (!ParseLiteral(context, segment)) { return(false); } } else { // This is the inside of a parameter if (!ParseParameter(context, segment)) { return(false); } } } else if (context.Current == Separator) { // We've reached the end of the segment break; } else { if (!ParseLiteral(context, segment)) { return(false); } } if (!context.Next()) { // We've reached the end of the string break; } } if (IsSegmentValid(context, segment)) { segments.Add(segment); return(true); } else { return(false); } }
private static bool ParseLiteral(TemplateParserContext context, TemplateSegment segment) { context.Mark(); string encoded; while (true) { if (context.Current == Separator) { encoded = context.Capture(); context.Back(); break; } else if (context.Current == OpenBrace) { if (!context.Next()) { // This is a dangling open-brace, which is not allowed context.Error = Resources.TemplateRoute_MismatchedParameter; return(false); } if (context.Current == OpenBrace) { // This is an 'escaped' brace in a literal, like "{{foo" - keep going. } else { // We've just seen the start of a parameter, so back up and return context.Back(); encoded = context.Capture(); context.Back(); break; } } else if (context.Current == CloseBrace) { if (!context.Next()) { // This is a dangling close-brace, which is not allowed context.Error = Resources.TemplateRoute_MismatchedParameter; return(false); } if (context.Current == CloseBrace) { // This is an 'escaped' brace in a literal, like "{{foo" - keep going. } else { // This is an unbalanced close-brace, which is not allowed context.Error = Resources.TemplateRoute_MismatchedParameter; return(false); } } if (!context.Next()) { encoded = context.Capture(); break; } } var decoded = encoded.Replace("}}", "}").Replace("{{", "}"); if (IsValidLiteral(context, decoded)) { segment.Parts.Add(TemplatePart.CreateLiteral(decoded)); return(true); } else { return(false); } }
private static bool ParseParameter(TemplateParserContext context, TemplateSegment segment) { context.Mark(); while (true) { if (context.Current == Separator) { // This is a dangling open-brace, which is not allowed context.Error = Resources.TemplateRoute_MismatchedParameter; return(false); } else if (context.Current == OpenBrace) { // If we see a '{' while parsing a parameter name it's invalid. We'll just accept it for now // and let the validation code for the name find it. } else if (context.Current == CloseBrace) { if (!context.Next()) { // This is the end of the string - and we have a valid parameter context.Back(); break; } if (context.Current == CloseBrace) { // This is an 'escaped' brace in a parameter name, which is not allowed. // We'll just accept it for now and let the validation code for the name find it. } else { // This is the end of the parameter context.Back(); break; } } if (!context.Next()) { // This is a dangling open-brace, which is not allowed context.Error = Resources.TemplateRoute_MismatchedParameter; return(false); } } var rawParameter = context.Capture(); // At this point, we need to parse the raw name for inline constraint, // default values and optional parameters. var templatePart = InlineRouteParameterParser.ParseRouteParameter(rawParameter); if (templatePart.IsCatchAll && templatePart.IsOptional) { context.Error = Resources.TemplateRoute_CatchAllCannotBeOptional; return(false); } if (templatePart.IsOptional && templatePart.DefaultValue != null) { // Cannot be optional and have a default value. // The only way to declare an optional parameter is to have a ? at the end, // hence we cannot have both default value and optional parameter within the template. // A workaround is to add it as a separate entry in the defaults argument. context.Error = Resources.TemplateRoute_OptionalCannotHaveDefaultValue; return(false); } var parameterName = templatePart.Name; if (IsValidParameterName(context, parameterName)) { segment.Parts.Add(templatePart); return(true); } else { return(false); } }
private static bool ParseParameter(TemplateParserContext context, TemplateSegment segment) { context.Mark(); while (true) { if (context.Current == OpenBrace) { // This is an open brace inside of a parameter, it has to be escaped if (context.Next()) { if (context.Current != OpenBrace) { // If we see something like "{p1:regex(^\d{3", we will come here. context.Error = Resources.TemplateRoute_UnescapedBrace; return(false); } } else { // This is a dangling open-brace, which is not allowed // Example: "{p1:regex(^\d{" context.Error = Resources.TemplateRoute_MismatchedParameter; return(false); } } else if (context.Current == CloseBrace) { // When we encounter Closed brace here, it either means end of the parameter or it is a closed // brace in the parameter, in that case it needs to be escaped. // Example: {p1:regex(([}}])\w+}. First pair is escaped one and last marks end of the parameter if (!context.Next()) { // This is the end of the string -and we have a valid parameter context.Back(); break; } if (context.Current == CloseBrace) { // This is an 'escaped' brace in a parameter name } else { // This is the end of the parameter context.Back(); break; } } if (!context.Next()) { // This is a dangling open-brace, which is not allowed context.Error = Resources.TemplateRoute_MismatchedParameter; return(false); } } var rawParameter = context.Capture(); var decoded = rawParameter.Replace("}}", "}").Replace("{{", "{"); // At this point, we need to parse the raw name for inline constraint, // default values and optional parameters. var templatePart = InlineRouteParameterParser.ParseRouteParameter(decoded); if (templatePart.IsCatchAll && templatePart.IsOptional) { context.Error = Resources.TemplateRoute_CatchAllCannotBeOptional; return(false); } if (templatePart.IsOptional && templatePart.DefaultValue != null) { // Cannot be optional and have a default value. // The only way to declare an optional parameter is to have a ? at the end, // hence we cannot have both default value and optional parameter within the template. // A workaround is to add it as a separate entry in the defaults argument. context.Error = Resources.TemplateRoute_OptionalCannotHaveDefaultValue; return(false); } var parameterName = templatePart.Name; if (IsValidParameterName(context, parameterName)) { segment.Parts.Add(templatePart); return(true); } else { return(false); } }
private static bool ParseSegment(TemplateParserContext context, List <RoutePatternPathSegment> segments) { Debug.Assert(context != null); Debug.Assert(segments != null); var parts = new List <RoutePatternPart>(); while (true) { var i = context.Index; if (context.Current == OpenBrace) { if (!context.MoveNext()) { // This is a dangling open-brace, which is not allowed context.Error = Resources.TemplateRoute_MismatchedParameter; return(false); } if (context.Current == OpenBrace) { // This is an 'escaped' brace in a literal, like "{{foo" context.Back(); if (!ParseLiteral(context, parts)) { return(false); } } else { // This is a parameter context.Back(); if (!ParseParameter(context, parts)) { return(false); } } } else { if (!ParseLiteral(context, parts)) { return(false); } } if (context.Current == Separator || context.AtEnd()) { // We've reached the end of the segment break; } if (context.Index <= i) { throw new InvalidProgramException("Infinite loop in the parser. This is a bug."); } } if (IsSegmentValid(context, parts)) { segments.Add(new RoutePatternPathSegment(null, parts.ToArray())); return(true); } else { return(false); } }