protected virtual void ParseFunctionStyleBlockInto(SerializableBindingDescription description, string block)
        {
            description.Converter = block;
            MoveNext();
            if (IsComplete)
            {
                throw new BindingException("Unterminated () pair for converter {0}", block);
            }

            ParseChildBindingDescriptionInto(description);
            SkipWhitespace();
            switch (CurrentChar)
            {
            case ')':
                MoveNext();
                break;

            case ',':
                MoveNext();
                ReadConverterParameterAndClosingBracket(description);
                break;

            default:
                throw new BindingException("Unexpected character {0} while parsing () contents", CurrentChar);
            }
        }
 private void ParseConverterParameter(string block, SerializableBindingDescription description)
 {
     ParseEquals(block);
     if (description.ConverterParameter != null)
     {
         Log.Warning("Overwriting existing ConverterParameter");
     }
     description.ConverterParameter = ReadValue();
 }
 private void ParseFallbackValue(string block, SerializableBindingDescription description)
 {
     ParseEquals(block);
     if (description.FallbackValue != null)
     {
         Log.Warning("Overwriting existing FallbackValue");
     }
     description.FallbackValue = ReadValue();
 }
 protected void ParseChildBindingDescriptionInto(SerializableBindingDescription description,
                                                 ParentIsLookingForComma parentIsLookingForComma = ParentIsLookingForComma.ParentIsLookingForComma)
 {
     SkipWhitespace();
     description.Function = "Single";
     description.Sources  = new[]
     {
         ParseBindingDescription(parentIsLookingForComma)
     };
 }
 protected void ReadConverterParameterAndClosingBracket(SerializableBindingDescription description)
 {
     SkipWhitespace();
     description.ConverterParameter = ReadValue();
     SkipWhitespace();
     if (CurrentChar != ')')
     {
         throw new BindingException("Unterminated () pair for converter {0}");
     }
     MoveNext();
 }
        private void ParseConverter(string block, SerializableBindingDescription description)
        {
            ParseEquals(block);
            var converter = ReadTargetPropertyName();

            if (!string.IsNullOrEmpty(description.Converter))
            {
                Log.Warning("Overwriting existing Converter with {0}", converter);
            }
            description.Converter = converter;
        }
 protected void ThrowExceptionIfPathAlreadyDefined(SerializableBindingDescription description)
 {
     if (description.Path != null &&
         description.Literal != null &&
         description.Function != null)
     {
         throw new BindingException(
                   "Make sure you are using ';' to separate multiple bindings. You cannot specify Path/Literal/Combiner more than once - position {0} in {1}",
                   CurrentIndex, FullText);
     }
 }
 protected virtual void ParseNonKeywordBlockInto(SerializableBindingDescription description, string block)
 {
     if (!IsComplete && CurrentChar == '(')
     {
         ParseFunctionStyleBlockInto(description, block);
     }
     else
     {
         ThrowExceptionIfPathAlreadyDefined(description);
         description.Path = block;
     }
 }
        protected override SerializableBindingDescription ParseOperatorWithLeftHand(SerializableBindingDescription description)
        {
            // Parse the operator
            var parsed       = ParseTwoCharacterOperator();
            var moveForwards = parsed.Item1;
            var combinerName = parsed.Item2;

            if (combinerName == null)
            {
                var gotCombinerName = SingleCharacterOperatorCombinerNames.TryGetValue(CurrentChar, out combinerName);
                if (gotCombinerName)
                {
                    moveForwards = 1;
                }
            }

            if (combinerName == null)
            {
                throw new BindingException("Unexpected operator starting with {0}", CurrentChar);
            }

            MoveNext(moveForwards);

            // now create the operator Combiner
            var child = new SerializableBindingDescription
            {
                Path               = description.Path,
                Literal            = description.Literal,
                Sources            = description.Sources,
                Function           = description.Function,
                Converter          = description.Converter,
                FallbackValue      = description.FallbackValue,
                ConverterParameter = description.ConverterParameter,
                Mode               = description.Mode
            };

            description.Converter          = null;
            description.ConverterParameter = null;
            description.FallbackValue      = null;
            description.Path     = null;
            description.Mode     = BindingMode.Default;
            description.Literal  = null;
            description.Function = combinerName;
            description.Sources  = new List <SerializableBindingDescription>
            {
                child,
                ParseBindingDescription(ParentIsLookingForComma.ParentIsLookingForComma)
            };

            return(description);
        }
        protected virtual SerializableBindingDescription ParseBindingDescription(
            ParentIsLookingForComma parentIsLookingForComma)
        {
            var description = new SerializableBindingDescription();

            SkipWhitespace();

            while (true)
            {
                ParseNextBindingDescriptionOptionInto(description);

                SkipWhitespace();
                if (IsComplete)
                {
                    return(description);
                }

                switch (CurrentChar)
                {
                case ',':
                    if (parentIsLookingForComma == ParentIsLookingForComma.ParentIsLookingForComma)
                    {
                        return(description);
                    }

                    MoveNext();
                    break;

                case ';':
                case ')':
                    return(description);

                default:
                    if (DetectOperator())
                    {
                        ParseOperatorWithLeftHand(description);
                    }
                    else
                    {
                        throw new BindingException(
                                  "Unexpected character {0} at position {1} in {2} - expected string-end, ',' or ';'",
                                  CurrentChar,
                                  CurrentIndex,
                                  FullText);
                    }
                    break;
                }
            }
        }
        protected virtual void ParseNextBindingDescriptionOptionInto(SerializableBindingDescription description)
        {
            if (IsComplete)
            {
                return;
            }

            var block = ReadTextUntilNonQuotedOccurrenceOfAnyOf(TerminatingCharacters().ToArray());

            block = block.Trim();
            if (string.IsNullOrEmpty(block))
            {
                HandleEmptyBlock(description);
                return;
            }

            switch (block)
            {
            case "Path":
                ParsePath(block, description);
                break;

            case "Converter":
                ParseConverter(block, description);
                break;

            case "ConverterParameter":
                ParseConverterParameter(block, description);
                break;

            case "CommandParameter":
                ParseCommandParameter(block, description);
                break;

            case "FallbackValue":
                ParseFallbackValue(block, description);
                break;

            case "Mode":
                ParseMode(block, description);
                break;

            default:
                ParseNonKeywordBlockInto(description, block);
                break;
            }
        }
        protected override void ParseNextBindingDescriptionOptionInto(SerializableBindingDescription description)
        {
            if (IsComplete)
            {
                return;
            }

            if (TryReadValue(AllowNonQuotedText.DoNotAllow, out var literal))
            {
                // for null, replace with LiteralNull
                literal = literal ?? LiteralNull;
                ThrowExceptionIfPathAlreadyDefined(description);
                description.Literal = literal;
                return;
            }

            base.ParseNextBindingDescriptionOptionInto(description);
        }
 private void ParseCommandParameter(string block, SerializableBindingDescription description)
 {
     if (!IsComplete &&
         CurrentChar == '(')
     {
         // following https://github.com/MvvmCross/MvvmCross/issues/704, if the next character is "(" then
         // we can treat CommandParameter as a normal non-keyword block
         ParseNonKeywordBlockInto(description, block);
     }
     else
     {
         ParseEquals(block);
         if (!string.IsNullOrEmpty(description.Converter))
         {
             Log.Warning("Overwriting existing Converter with CommandParameter");
         }
         description.Converter          = "CommandParameter";
         description.ConverterParameter = ReadValue();
     }
 }
        protected override void HandleEmptyBlock(SerializableBindingDescription description)
        {
            if (IsComplete)
            {
                return;
            }

            if (CurrentChar == '(')
            {
                MoveNext();
                ParseChildBindingDescriptionInto(description, ParentIsLookingForComma.ParentIsNotLookingForComma);

                SkipWhitespace();
                if (IsComplete || CurrentChar != ')')
                {
                    throw new BindingException("Unterminated () pair");
                }
                MoveNext();
                SkipWhitespace();
            }
        }
        protected override void ParseFunctionStyleBlockInto(SerializableBindingDescription description, string block)
        {
            description.Function = block;
            MoveNext();
            if (IsComplete)
            {
                throw new BindingException("Unterminated () pair for combiner {0}", block);
            }

            var terminationFound = false;
            var sources          = new List <SerializableBindingDescription>();

            while (!terminationFound)
            {
                SkipWhitespace();
                sources.Add(ParseBindingDescription(ParentIsLookingForComma.ParentIsLookingForComma));
                SkipWhitespace();
                if (IsComplete)
                {
                    throw new BindingException("Unterminated () while parsing combiner {0}", block);
                }

                switch (CurrentChar)
                {
                case ')':
                    MoveNext();
                    terminationFound = true;
                    break;

                case ',':
                    MoveNext();
                    break;

                default:
                    throw new BindingException("Unexpected character {0} while parsing () combiner contents for {1}", CurrentChar, block);
                }
            }

            description.Sources = sources.ToArray();
        }
 private void ParseMode(string block, SerializableBindingDescription description)
 {
     ParseEquals(block);
     description.Mode = ReadBindingMode();
 }
 protected virtual SerializableBindingDescription ParseOperatorWithLeftHand(
     SerializableBindingDescription description)
 {
     throw new BindingException("Operators not expected in base SwissBinding");
 }
 protected virtual void HandleEmptyBlock(SerializableBindingDescription description)
 {
     // default implementation doesn't do any special handling on an empty block
 }
 private void ParsePath(string block, SerializableBindingDescription description)
 {
     ParseEquals(block);
     ThrowExceptionIfPathAlreadyDefined(description);
     description.Path = ReadTextUntilNonQuotedOccurrenceOfAnyOf(',', ';');
 }