示例#1
0
        public void Merge(HoconObject other)
        {
            var thisItems  = Items;
            var otherItems = other.Items;

            foreach (var otherItem in otherItems)
            {
                if (thisItems.ContainsKey(otherItem.Key))
                {
                    //other key was present in this object.
                    //if we have a value, just ignore the other value, unless it is an object
                    var thisItem = thisItems[otherItem.Key];

                    //if both values are objects, merge them
                    if (thisItem.IsObject() && otherItem.Value.IsObject())
                    {
                        thisItem.GetObject().Merge(otherItem.Value.GetObject());
                    }
                }
                else
                {
                    //other key was not present in this object, just copy it over
                    Items.Add(otherItem.Key, otherItem.Value);
                }
            }
        }
示例#2
0
        public virtual void Merge(HoconObject other)
        {
            var keys = other.Keys.ToArray();

            foreach (var key in keys)
            {
                var quotedKey = $"\"{key}\"";
                if (!ContainsKey(key))
                {
                    base[key] = other[quotedKey];
                    continue;
                }

                var thisItem  = this[quotedKey];
                var otherItem = other[quotedKey].Value;
                if (thisItem.Type == HoconType.Object && otherItem.Type == HoconType.Object)
                {
                    thisItem.GetObject().Merge(otherItem.GetObject());
                }
                else
                {
                    thisItem.SetValue(otherItem);
                }
            }
        }
示例#3
0
 public void FallbackMerge(HoconObject other)
 {
     foreach (var kvp in other)
     {
         var path = kvp.Value.Path;
         if (!TryGetValue(path, out _))
         {
             var        currentObject = this;
             HoconField newField      = null;
             foreach (var key in path)
             {
                 newField = currentObject.GetOrCreateKey(key);
                 if (newField.Type == HoconType.Empty)
                 {
                     var emptyValue = new HoconValue(newField);
                     emptyValue.Add(new HoconObject(emptyValue));
                     newField.SetValue(emptyValue);
                 }
                 currentObject = newField.GetObject();
             }
             newField.SetValue(kvp.Value.Value);
         }
         else
         {
             if (kvp.Value.Type == HoconType.Object)
             {
                 FallbackMerge(kvp.Value.GetObject());
             }
         }
     }
 }
示例#4
0
        public virtual bool TryGetObject(out HoconObject result)
        {
            result = null;
            if (Type != HoconType.Object)
            {
                return(false);
            }

            var objects = this
                          .Where(value => value.Type == HoconType.Object)
                          .Select(value => value.GetObject()).ToList();

            switch (objects.Count)
            {
            case 0:
                break;

            case 1:
                result = objects[0];
                break;

            default:
                result = new HoconMergedObject(this, objects);
                break;
            }
            return(true);
        }
示例#5
0
        public override void Merge(HoconObject other)
        {
            var parent = (HoconValue)Parent;

            parent.Add(other);

            Objects.Add(other);
            base.Merge(other);
        }
示例#6
0
        /// <inheritdoc />
        public IHoconElement Clone(IHoconElement newParent)
        {
            var clone = new HoconObject(newParent);

            foreach (var kvp in this)
            {
                clone.SetField(kvp.Key, kvp.Value.Clone(clone) as HoconField);
            }
            return(clone);
        }
示例#7
0
        /// <summary>
        ///     Retrieves the merged <see cref="HoconObject" /> backing the <see cref="HoconField" /> field
        ///     associated with the supplied <see cref="string" /> key.
        /// </summary>
        /// <param name="key">The <see cref="string" /> key associated with the field to retrieve.</param>
        /// <param name="result">
        ///     When this method returns, contains the backing <see cref="HoconObject" />
        ///     of the <see cref="HoconField" /> associated with the specified key, if the key is found;
        ///     otherwise, null. This parameter is passed uninitialized.
        /// </param>
        /// <returns>
        ///     <c>true</c> if the <see cref="HoconObject" /> contains a <see cref="HoconField" /> field with the the specified key
        ///     and the <see cref="HoconField.Type" /> is of type <see cref="HoconType.Object" />; otherwise, <c>false</c>.
        /// </returns>
        public bool TryGetObject(string key, out HoconObject result)
        {
            result = null;
            if (!TryGetField(key, out var field))
            {
                return(false);
            }

            result = field.GetObject();
            return(true);
        }
示例#8
0
        /// <summary>
        ///     Wraps this <see cref="HoconValue" /> into a new <see cref="HoconObject" /> at the specified key.
        /// </summary>
        /// <param name="key">The key designated to be the new root element.</param>
        /// <returns>A new HOCON root.</returns>
        /// <remarks>
        ///     Immutable. Performs a deep copy on this <see cref="HoconValue" /> first.
        /// </remarks>
        public HoconRoot AtKey(string key)
        {
            var value = new HoconValue(null);
            var obj   = new HoconObject(value);
            var field = new HoconField(key, obj);

            field.SetValue(Clone(field) as HoconValue);
            obj.Add(key, field);
            value.Add(obj);

            return(new HoconRoot(value));
        }
示例#9
0
        public HoconField(string key, HoconObject parent)
        {
            if (string.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException(nameof(key));
            }

            Path = new HoconPath(parent.Path)
            {
                key
            };
            Parent = parent;
        }
示例#10
0
        internal void EnsureFieldIsObject()
        {
            if (Type == HoconType.Object)
            {
                return;
            }

            var v = new HoconValue(this);
            var o = new HoconObject(v);

            v.Add(o);
            _internalValues.Add(v);
        }
示例#11
0
文件: Parser.cs 项目: nagytech/HOCON
        private HoconField ParseField(HoconObject owner)
        {
            // sanity check
            if (_tokens.Current.Type != TokenType.LiteralValue)
            {
                throw HoconParserException.Create(_tokens.Current, Path,
                                                  $"Failed to parse Hocon field. Expected start of field {TokenType.LiteralValue}, " +
                                                  $"found {_tokens.Current.Type} instead.");
            }

            var pathDelta = ParseKey();

            if (_tokens.Current.IsNonSignificant())
            {
                ConsumeWhitelines();
            }

            // sanity check
            if (_tokens.Current.Type != TokenType.Assign &&
                _tokens.Current.Type != TokenType.StartOfObject &&
                _tokens.Current.Type != TokenType.PlusEqualAssign)
            {
                throw HoconParserException.Create(_tokens.Current, Path,
                                                  $"Failed to parse Hocon field. Expected {TokenType.Assign}, {TokenType.StartOfObject} " +
                                                  $"or {TokenType.PlusEqualAssign}, found {{_tokens.Current.Type}} instead.");
            }

            // sanity check
            if (pathDelta == null || pathDelta.Count == 0)
            {
                throw HoconParserException.Create(_tokens.Current, Path,
                                                  "Failed to parse Hocon field. ParseField() was called with null or empty path");
            }

            List <HoconField> childInPath = owner.TraversePath(pathDelta);

            Path.AddRange(pathDelta);
            HoconField currentField = childInPath[childInPath.Count - 1];

            var parsedValue = ParseValue(currentField);

            foreach (var removedSub in currentField.SetValue(parsedValue))
            {
                _substitutions.Remove(removedSub);
            }

            Path.RemoveRange(Path.Count - pathDelta.Count, pathDelta.Count);
            return(childInPath[0]);
        }
示例#12
0
        public virtual void Merge(HoconObject other)
        {
            var keys = other.Keys.ToArray();

            foreach (var key in keys)
            {
                if (ContainsKey(key))
                {
                    var thisItem  = this[key];
                    var otherItem = other[key];
                    if (thisItem.Type == HoconType.Object && otherItem.Type == HoconType.Object)
                    {
                        thisItem.GetObject().Merge(otherItem.GetObject());
                        continue;
                    }
                }
                this[key] = other[key];
            }
        }
示例#13
0
        private void ParseField(HoconObject owner)
        {
            // sanity check
            if (_tokens.Current.IsNonSignificant() || _tokens.Current.Type != TokenType.LiteralValue)
            {
                throw HoconParserException.Create(_tokens.Current, Path,
                                                  $"Failed to parse Hocon field. Expected start of field {TokenType.LiteralValue}, " +
                                                  $"found {_tokens.Current.Type} instead.");
            }

            var relativePath = ParseKey();

            if (_tokens.Current.Type == TokenType.EndOfLine)
            {
                _tokens.ToNextSignificantLine();
            }

            // sanity check
            if (_tokens.Current.Type != TokenType.Assign &&
                _tokens.Current.Type != TokenType.StartOfObject &&
                _tokens.Current.Type != TokenType.PlusEqualAssign)
            {
                throw HoconParserException.Create(_tokens.Current, Path,
                                                  $"Failed to parse Hocon field. Expected {TokenType.Assign}, {TokenType.StartOfObject} " +
                                                  $"or {TokenType.PlusEqualAssign}, found {_tokens.Current.Type} instead.");
            }

            // sanity check
            if (relativePath == null || relativePath.Count == 0)
            {
                throw HoconParserException.Create(_tokens.Current, Path,
                                                  "Failed to parse Hocon field. Null or empty path");
            }

            Path.AddRange(relativePath);

            var currentField = owner.TraversePath(relativePath);

            currentField.SetValue(ParseValue(currentField));

            Path.RemoveRange(Path.Count - relativePath.Count, relativePath.Count);
        }
示例#14
0
 /// <summary>
 /// Retrieves an object from the specified path in the configuration.
 /// </summary>
 /// <param name="path">The path that contains the value to retrieve.</param>
 /// <param name="default">The default value to return if the value doesn't exist.</param>
 /// <returns>The double value defined in the specified path.</returns>
 public HoconObject GetObject(string path, HoconObject @default = null)
 => GetObject(HoconPath.Parse(path), @default);
示例#15
0
        // The owner in this context can be either an object or an array.
        private void ParseObject(ref HoconValue owner)
        {
            if (owner == null)
            {
                throw HoconParserException.Create(_tokens.Current, Path,
                                                  "ParseObject called with null parent.");
            }

            // Sanity check
            if (_tokens.Current.Type != TokenType.StartOfObject)
            {
                throw HoconParserException.Create(_tokens.Current, Path,
                                                  $"Failed to parse Hocon object. Expected `{TokenType.StartOfObject}`, found `{_tokens.Current.Type}` instead.");
            }

            // Consume curly bracket
            _tokens.ToNextSignificant();

            var hoconObject = owner.GetObject();

            if (hoconObject == null)
            {
                hoconObject = new HoconObject(owner);
                owner.Add(hoconObject);
            }

            var valueWasParsed = false;
            var parsing        = true;

            while (parsing)
            {
                switch (_tokens.Current.Type)
                {
                case TokenType.Include:
                    if (valueWasParsed)
                    {
                        throw HoconParserException.Create(_tokens.Current, Path,
                                                          $"Failed to parse Hocon object. Expected `{TokenType.Comma}` or `{TokenType.EndOfLine}`, " +
                                                          $"found `{_tokens.Current.Type}` instead.");
                    }

                    owner.ReParent(ParseInclude());
                    valueWasParsed = true;
                    break;

                case TokenType.LiteralValue:
                    if (_tokens.Current.IsNonSignificant())
                    {
                        _tokens.ToNextSignificant();
                    }

                    if (_tokens.Current.Type != TokenType.LiteralValue)
                    {
                        break;
                    }

                    if (valueWasParsed)
                    {
                        throw HoconParserException.Create(_tokens.Current, Path,
                                                          $"Failed to parse Hocon object. Expected `{TokenType.Comma}` or `{TokenType.EndOfLine}`, " +
                                                          $"found `{_tokens.Current.Type}` instead.");
                    }

                    ParseField(hoconObject);
                    valueWasParsed = true;
                    break;

                case TokenType.Comment:
                case TokenType.EndOfLine:
                    valueWasParsed = false;
                    _tokens.ToNextSignificantLine();
                    break;

                case TokenType.Comma:
                    if (!valueWasParsed)
                    {
                        throw HoconParserException.Create(_tokens.Current, Path,
                                                          $"Failed to parse Hocon object. Expected `{TokenType.Assign}` or `{TokenType.StartOfObject}`, " +
                                                          $"found `{_tokens.Current.Type}` instead.");
                    }

                    valueWasParsed = false;
                    _tokens.ToNextSignificant();
                    break;

                case TokenType.EndOfObject:
                    valueWasParsed = false;
                    parsing        = false;
                    break;

                case TokenType.EndOfFile:
                    throw HoconParserException.Create(_tokens.Current, Path,
                                                      $"Failed to parse Hocon object. Expected {TokenType.EndOfObject} but found {_tokens.Current.Type} instead.");

                default:
                    throw HoconParserException.Create(_tokens.Current, Path,
                                                      $"Failed to parse Hocon object. Unexpected token `{_tokens.Current.Type}`.");
                }
            }

            // Consume the closing curly bracket.
            _tokens.ToNextSignificant();
        }
示例#16
0
 public override void Merge(HoconObject other)
 {
     ((HoconField)Parent).Value.Add(other.Clone(((HoconField)Parent).Value));
     base.Merge(other);
 }
示例#17
0
文件: Parser.cs 项目: nagytech/HOCON
        // The owner in this context can be either an object or an array.
        private HoconObject ParseObject(IHoconElement owner)
        {
            var hoconObject = new HoconObject(owner);

            if (_tokens.Current.Type != TokenType.StartOfObject &&
                _tokens.Current.Type != TokenType.LiteralValue &&
                _tokens.Current.Type != TokenType.Include)
            {
                throw HoconParserException.Create(_tokens.Current, Path,
                                                  $"Failed to parse Hocon object. Expected `{TokenType.StartOfObject}` or `{TokenType.LiteralValue}, " +
                                                  $"found `{_tokens.Current.Type}` instead.");
            }

            var headless = true;

            if (_tokens.Current.Type == TokenType.StartOfObject)
            {
                headless = false;
                ConsumeWhitelines();
            }

            IHoconElement lastValue = null;
            var           parsing   = true;

            while (parsing)
            {
                switch (_tokens.Current.Type)
                {
                case TokenType.Include:
                    if (lastValue != null)
                    {
                        throw HoconParserException.Create(_tokens.Current, Path,
                                                          $"Failed to parse Hocon object. Expected `{TokenType.Comma}` or `{TokenType.EndOfLine}`, " +
                                                          $"found `{_tokens.Current.Type}` instead.");
                    }

                    lastValue = ParseInclude(hoconObject);
                    break;

                case TokenType.LiteralValue:
                    if (_tokens.Current.IsNonSignificant())
                    {
                        ConsumeWhitespace();
                    }
                    if (_tokens.Current.Type != TokenType.LiteralValue)
                    {
                        break;
                    }

                    if (lastValue != null)
                    {
                        throw HoconParserException.Create(_tokens.Current, Path,
                                                          $"Failed to parse Hocon object. Expected `{TokenType.Comma}` or `{TokenType.EndOfLine}`, " +
                                                          $"found `{_tokens.Current.Type}` instead.");
                    }

                    lastValue = ParseField(hoconObject);
                    break;

                // TODO: can an object be declared floating without being assigned to a field?
                //case TokenType.StartOfObject:
                case TokenType.Comment:
                case TokenType.EndOfLine:
                    switch (lastValue)
                    {
                    case null:
                        ConsumeWhitelines();
                        break;

                    case HoconField _:
                        break;

                    default:
                        ((HoconValue)hoconObject.Parent).Add(lastValue.GetObject());
                        break;
                    }
                    lastValue = null;
                    ConsumeWhitelines();
                    break;

                case TokenType.Comma:
                    switch (lastValue)
                    {
                    case null:
                        throw HoconParserException.Create(_tokens.Current, Path,
                                                          $"Failed to parse Hocon object. Expected `{TokenType.Assign}` or `{TokenType.StartOfObject}`, " +
                                                          $"found `{_tokens.Current.Type}` instead.");

                    case HoconField _:
                        break;

                    default:
                        ((HoconValue)hoconObject.Parent).Add(lastValue.GetObject());
                        break;
                    }
                    lastValue = null;
                    ConsumeWhitelines();
                    break;

                case TokenType.EndOfObject:
                case TokenType.EndOfFile:
                    if (headless && _tokens.Current.Type != TokenType.EndOfFile)
                    {
                        throw HoconParserException.Create(_tokens.Current, Path,
                                                          $"Failed to parse Hocon object. Expected {TokenType.EndOfFile} but found {_tokens.Current.Type} instead.");
                    }

                    if (!headless && _tokens.Current.Type != TokenType.EndOfObject)
                    {
                        throw HoconParserException.Create(_tokens.Current, Path,
                                                          $"Failed to parse Hocon object. Expected {TokenType.EndOfObject} but found {_tokens.Current.Type} instead.");
                    }

                    switch (lastValue)
                    {
                    case null:
                        break;

                    case HoconField _:
                        break;

                    default:
                        ((HoconValue)hoconObject.Parent).Add(lastValue.GetObject());
                        break;
                    }
                    lastValue = null;
                    parsing   = false;
                    break;

                default:
                    throw HoconParserException.Create(_tokens.Current, Path,
                                                      $"Failed to parse Hocon object. Unexpected token `{_tokens.Current.Type}`.");
                }
            }
            if (_tokens.Current.Type == TokenType.EndOfObject)
            {
                _tokens.Next();
            }
            return(hoconObject);
        }
示例#18
0
        static HoconObject()
        {
            var value = new HoconValue(null);

            _empty = new HoconObject(value);
        }
示例#19
0
        /// <inheritdoc cref="GetObject(string,HoconObject)"/>
        public HoconObject GetObject(HoconPath path, HoconObject @default = null)
        {
            var value = GetNode(path);

            return(value == null ? @default : value.GetObject());
        }
示例#20
0
        private void ParseObject(HoconValue owner, bool root, string currentPath)
        {
            try
            {
                PushDiagnostics("{");

                if (owner.IsObject())
                {
                    //the value of this KVP is already an object
                }
                else
                {
                    //the value of this KVP is not an object, thus, we should add a new
                    owner.NewValue(new HoconObject());
                }

                HoconObject currentObject = owner.GetObject();

                while (!_reader.EoF)
                {
                    Token t = _reader.PullNext();
                    switch (t.Type)
                    {
                    case TokenType.Include:
                        var included      = _includeCallback(t.Value);
                        var substitutions = included.Substitutions;
                        foreach (var substitution in substitutions)
                        {
                            //fixup the substitution, add the current path as a prefix to the substitution path
                            substitution.Path = currentPath + "." + substitution.Path;
                        }
                        _substitutions.AddRange(substitutions);
                        var otherObj = included.Value.GetObject();
                        owner.GetObject().Merge(otherObj);

                        break;

                    case TokenType.EoF:
                        if (!string.IsNullOrEmpty(currentPath))
                        {
                            throw new HoconParserException(string.Format("Expected end of object but found EoF {0}", GetDiagnosticsStackTrace()));
                        }
                        break;

                    case TokenType.Key:
                        HoconValue value    = currentObject.GetOrCreateKey(t.Value);
                        var        nextPath = currentPath == "" ? t.Value : currentPath + "." + t.Value;
                        ParseKeyContent(value, nextPath);
                        if (!root)
                        {
                            return;
                        }
                        break;

                    case TokenType.ObjectEnd:
                        return;
                    }
                }
            }
            finally
            {
                PopDiagnostics();
            }
        }