class Hocon::Impl::ResolveSource
Constants
- ConfigBugOrBrokenError
- ConfigNotResolvedError
Attributes
'path_from_root' is used for knowing the chain of parents we used to get here. null if we should assume we are not a descendant of the root. the root itself should be a node in this if non-null.
'path_from_root' is used for knowing the chain of parents we used to get here. null if we should assume we are not a descendant of the root. the root itself should be a node in this if non-null.
Public Class Methods
# File lib/hocon/impl/resolve_source.rb, line 20 def initialize(root, path_from_root = nil) @root = root @path_from_root = path_from_root end
Private Class Methods
# File lib/hocon/impl/resolve_source.rb, line 291 def self.find_in_object_impl(obj, path, parents = nil) begin # we 'll fail if anything along the path can' t # be looked at without resolving. find_in_object_impl_impl(obj, path, nil) rescue ConfigNotResolvedError => e raise Hocon::Impl::ConfigImpl.improve_not_resolved(path, e) end end
# File lib/hocon/impl/resolve_source.rb, line 301 def self.find_in_object_impl_impl(obj, path, parents) key = path.first remainder = path.remainder if Hocon::Impl::ConfigImpl.trace_substitution_enabled Hocon::Impl::ConfigImpl.trace("*** looking up '#{key}' in #{obj}") end v = obj.attempt_peek_with_partial_resolve(key) new_parents = parents == nil ? Node.new(obj) : parents.prepend(obj) if remainder == nil ValueWithPath.new(v, new_parents) else if v.is_a?(Hocon::Impl::AbstractConfigObject) find_in_object_impl_impl(v, remainder, new_parents) else ValueWithPath.new(nil, new_parents) end end end
returns null if the replacement results in deleting all the nodes.
# File lib/hocon/impl/resolve_source.rb, line 322 def self.replace(list, old, replacement) child = list.head unless child.equal?(old) raise ConfigBugOrBrokenError.new("Can only replace() the top node we're resolving; had " + child + " on top and tried to replace " + old + " overall list was " + list) end parent = list.tail == nil ? nil : list.tail.head if replacement == nil || !replacement.is_a?(Hocon::Impl::Container) if parent == nil return nil else # we are deleting the child from the stack of containers # because it's either going away or not a container new_parent = parent.replace_child(old, nil) return replace(list.tail, parent, new_parent) end else # we replaced the container with another container if parent == nil return Node.new(replacement) else new_parent = parent.replace_child(old, replacement) new_tail = replace(list.tail, parent, new_parent) if new_tail != nil return new_tail.prepend(replacement) else return Node.new(replacement) end end end end
Public Instance Methods
as a side effect, findInObject() will have to resolve all parents of the child being peeked, but NOT the child itself.Caller has to resolve the child itself if Hocon::Impl::ResolveSource::ValueWithPath#value can be null but the ValueWithPath instance itself should not be.
# File lib/hocon/impl/resolve_source.rb, line 29 def find_in_object(obj, context, path) # resolve ONLY portions of the object which are along our path if Hocon::Impl::ConfigImpl.trace_substitution_enabled Hocon::Impl::ConfigImpl.trace("*** finding '#{path}' in #{obj}") end restriction = context.restrict_to_child partially_resolved = context.restrict(path).resolve(obj, self.class.new(obj)) new_context = partially_resolved.context.restrict(restriction) if partially_resolved.value.is_a?(Hocon::Impl::AbstractConfigObject) pair = self.class.find_in_object_impl(partially_resolved.value, path) ResultWithPath.new(Hocon::Impl::ResolveResult.make(new_context, pair.value), pair.path_from_root) else raise ConfigBugOrBrokenError.new("resolved object to non-object " + obj + " to " + partially_resolved) end end
# File lib/hocon/impl/resolve_source.rb, line 45 def lookup_subst(context, subst, prefix_length) if Hocon::Impl::ConfigImpl.trace_substitution_enabled Hocon::Impl::ConfigImpl.trace("searching for #{subst}", context.depth) end if Hocon::Impl::ConfigImpl.trace_substitution_enabled Hocon::Impl::ConfigImpl.trace("#{subst} - looking up relative to file it occurred in", context.depth) end # First we look up the full path, which means relative to the # included file if we were not a root file result = find_in_object(@root, context, subst.path) if result.result.value == nil # Then we want to check relative to the root file.We don 't # want the prefix we were included at to be used when looking # up env variables either. unprefixed = subst.path.sub_path_to_end(prefix_length) if prefix_length > 0 if Hocon::Impl::ConfigImpl.trace_substitution_enabled Hocon::Impl::ConfigImpl.trace( unprefixed + " - looking up relative to parent file", result.result.context.depth) end result = find_in_object(@root, result.result.context, unprefixed) end if result.result.value == nil && result.result.context.options.use_system_environment if Hocon::Impl::ConfigImpl.trace_substitution_enabled Hocon::Impl::ConfigImpl.trace( "#{unprefixed} - looking up in system environment", result.result.context.depth) end result = find_in_object(Hocon::Impl::ConfigImpl.env_variables_as_config_object, context, unprefixed) end end if Hocon::Impl::ConfigImpl.trace_substitution_enabled Hocon::Impl::ConfigImpl.trace( "resolved to #{result}", result.result.context.depth) end result end
# File lib/hocon/impl/resolve_source.rb, line 92 def push_parent(parent) unless parent raise ConfigBugOrBrokenError.new("can't push null parent") end if Hocon::Impl::ConfigImpl.trace_substitution_enabled Hocon::Impl::ConfigImpl.trace("pushing parent #{parent} ==root #{(parent == root)} onto #{self}") end if @path_from_root == nil if parent.equal?(@root) return self.class.new(@root, Node.new(parent)) else if Hocon::Impl::ConfigImpl.trace_substitution_enabled # this hasDescendant check is super-expensive so it's a # trace message rather than an assertion if @root.has_descendant?(parent) Hocon::Impl::ConfigImpl.trace( "***** BUG ***** tried to push parent #{parent} without having a path to it in #{self}") end end # ignore parents if we aren't proceeding from the # root return self end else parent_parent = @path_from_root.head if Hocon::Impl::ConfigImpl.trace_substitution_enabled # this hasDescendant check is super-expensive so it's a # trace message rather than an assertion if parent_parent != nil && !parent_parent.has_descendant?(parent) Hocon::Impl::ConfigImpl.trace( "***** BUG ***** trying to push non-child of #{parent_parent}, non-child was #{parent}") end end self.class.new(@root, @path_from_root.prepend(parent)) end end
# File lib/hocon/impl/resolve_source.rb, line 140 def replace_current_parent(old, replacement) if Hocon::Impl::ConfigImpl.trace_substitution_enabled Hocon::Impl::ConfigImpl.trace("replaceCurrentParent old #{old}@#{old.hash} replacement " + "#{replacement}@#{old.hash} in #{self}") end if old.equal?(replacement) self elsif @path_from_root != nil new_path = self.class.replace(@path_from_root, old, replacement) if Hocon::Impl::ConfigImpl.trace_substitution_enabled Hocon::Impl::ConfigImpl.trace("replaced #{old} with #{replacement} in #{self}") Hocon::Impl::ConfigImpl.trace("path was: #{@path_from_root} is now #{new_path}") end # if we end up nuking the root object itself, we replace it with an # empty root if new_path != nil return self.class.new(new_path.last, new_path) else return self.class.new(Hocon::Impl::SimpleConfigObject.empty) end else if old.equal?(@root) return self.class.new(root_must_be_obj(replacement)) else raise ConfigBugOrBrokenError.new("attempt to replace root #{root} with #{replacement}") end end end
replacement may be null to delete
# File lib/hocon/impl/resolve_source.rb, line 170 def replace_within_current_parent(old, replacement) if Hocon::Impl::ConfigImpl.trace_substitution_enabled Hocon::Impl::ConfigImpl.trace("replaceWithinCurrentParent old #{old}@#{old.hash}" + " replacement #{replacement}@#{old.hash} in #{self}") end if old.equal?(replacement) self elsif @path_from_root != nil parent = @path_from_root.head new_parent = parent.replace_child(old, replacement) return replace_current_parent(parent, new_parent.is_a?(Hocon::Impl::Container) ? new_parent : nil) else if old.equal?(@root) && replacement.is_a?(Hocon::Impl::Container) return self.class.new(root_must_be_obj(replacement)) else raise ConfigBugOrBrokenError.new("replace in parent not possible #{old} with #{replacement}" + " in #{self}") end end end
# File lib/hocon/impl/resolve_source.rb, line 132 def reset_parents if @path_from_root == nil this else self.class.new(@root) end end
# File lib/hocon/impl/resolve_source.rb, line 191 def to_s "ResolveSource(root=#{@root}, pathFromRoot=#{@path_from_root})" end
Private Instance Methods
# File lib/hocon/impl/resolve_source.rb, line 283 def root_must_be_obj(value) if value.is_a?(Hocon::Impl::AbstractConfigObject) value else Hocon::Impl::SimpleConfigObject.empty end end