module Hocon::Impl::AbstractConfigValue

Trying very hard to avoid a parent reference in config values; when you have a tree like this, the availability of parent() tends to result in a lot of improperly-factored and non-modular code. Please don't add parent().

Constants

ConfigBugOrBrokenError
ConfigImplUtil
ResolveStatus

Attributes

origin[R]

Public Class Methods

has_descendant_in_list?(list, descendant) click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 89
def self.has_descendant_in_list?(list, descendant)
  list.each do |v|
    if v.equal?(descendant)
      return true
    end
  end
  # now the expensive traversal
  list.each do |v|
    if v.is_a?(Hocon::Impl::Container) && v.has_descendant?(descendant)
      return true
    end
  end
  false
end
indent(sb, indent_size, options) click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 294
def self.indent(sb, indent_size, options)
  if options.formatted?
    remaining = indent_size
    while remaining > 0
      sb << "    "
      remaining -= 1
    end
  end
end
new(origin) click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 26
def initialize(origin)
  @origin = origin
end
replace_child_in_list(list, child, replacement) click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 66
def self.replace_child_in_list(list, child, replacement)
  i = 0
  while (i < list.size) && (! list[i].equal?(child))
    i += 1
  end
  if (i == list.size)
    raise ConfigBugOrBrokenError, "tried to replace #{child} which is not in #{list}"
  end

  new_stack = list.clone
  if ! replacement.nil?
    new_stack[i] = replacement
  else
    new_stack.delete(i)
  end

  if new_stack.empty?
    nil
  else
    new_stack
  end
end

Public Instance Methods

==(other) click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 263
def ==(other)
  # note that "origin" is deliberately NOT part of equality
  if other.is_a?(Hocon::Impl::AbstractConfigValue)
    can_equal(other) &&
        value_type == other.value_type &&
        ConfigImplUtil.equals_handling_nil?(unwrapped, other.unwrapped)
  else
    false
  end
end
at_key(key) click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 356
def at_key(key)
  at_key_with_origin(Hocon::Impl::SimpleConfigOrigin.new_simple("at_key(#{key})"), key)
end
at_key_with_origin(origin, key) click to toggle source

Renamed this to be consistent with the other at_key* overloaded methods

# File lib/hocon/impl/abstract_config_value.rb, line 361
def at_key_with_origin(origin, key)
  m = {key=>self}
  Hocon::Impl::SimpleConfigObject.new(origin, m).to_config
end
at_path(path_expression) click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 378
def at_path(path_expression)
  origin = Hocon::Impl::SimpleConfigOrigin.new_simple("at_path(#{path_expression})")
  at_path_with_origin(origin, Hocon::Impl::Path.new_path(path_expression))
end
at_path_with_origin(origin, path) click to toggle source

In java this is an overloaded version of atPath

# File lib/hocon/impl/abstract_config_value.rb, line 367
def at_path_with_origin(origin, path)
  parent = path.parent
  result = at_key_with_origin(origin, path.last)
  while not parent.nil? do
    key = parent.last
    result = result.at_key_with_origin(origin, key)
    parent = parent.parent
  end
  result
end
can_equal(other) click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 259
def can_equal(other)
  other.is_a?(Hocon::Impl::AbstractConfigValue)
end
construct_delayed_merge(origin, stack) click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 161
def construct_delayed_merge(origin, stack)
  # TODO: this might not work because ConfigDelayedMerge inherits
  # from this class, so we can't `require` it from this file
  require 'hocon/impl/config_delayed_merge'
  Hocon::Impl::ConfigDelayedMerge.new(origin, stack)
end
delay_merge(stack, fallback) click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 180
def delay_merge(stack, fallback)
  # if we turn out to be an object, and the fallback also does,
  # then a merge may be required.
  # if we contain a substitution, resolving it may need to look
  # back to the fallback
  new_stack = stack.clone
  new_stack << fallback
  # TODO: this might not work because AbstractConfigObject inherits
  # from this class, so we can't `require` it from this file
  construct_delayed_merge(Hocon::Impl::AbstractConfigObject.merge_origins(new_stack), new_stack)
end
hash() click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 274
def hash
  # note that "origin" is deliberately NOT part of equality
  unwrapped_value = unwrapped
  if unwrapped_value.nil?
    0
  else
    unwrapped_value.hash
  end
end
ignores_fallbacks?() click to toggle source

this is virtualized rather than a field because only some subclasses really need to store the boolean, and they may be able to pack it with another boolean to save space.

# File lib/hocon/impl/abstract_config_value.rb, line 139
def ignores_fallbacks?
  # if we are not resolved, then somewhere in this value there's
  # a substitution that may need to look at the fallbacks.
  resolve_status == Hocon::Impl::ResolveStatus::RESOLVED
end
inspect() click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 290
def inspect
  to_s
end
merged_stack_with_non_object(stack, fallback) click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 204
def merged_stack_with_non_object(stack, fallback)
  require_not_ignoring_fallbacks

  if resolve_status == ResolveStatus::RESOLVED
    # falling back to a non-object doesn't merge anything, and also
    # prohibits merging any objects that we fall back to later.
    # so we have to switch to ignoresFallbacks mode.
    with_fallbacks_ignored
  else
    # if unresolved we may have to look back to fallbacks as part of
    # the resolution process, so always delay
    delay_merge(stack, fallback)
  end
end
merged_stack_with_object(stack, fallback) click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 192
def merged_stack_with_object(stack, fallback)
  require_not_ignoring_fallbacks

  # TODO: this might not work because AbstractConfigObject inherits
  # from this class, so we can't `require` it from this file
  if self.is_a?(Hocon::Impl::AbstractConfigObject)
    raise ConfigBugOrBrokenError, "Objects must reimplement merged_with_object"
  end

  merged_stack_with_non_object(stack, fallback)
end
merged_stack_with_the_unmergeable(stack, fallback) click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 168
def merged_stack_with_the_unmergeable(stack, fallback)
  require_not_ignoring_fallbacks

  # if we turn out to be an object, and the fallback also does,
  # then a merge may be required; delay until we resolve.
  new_stack = stack.clone
  new_stack.concat(fallback.unmerged_values)
  # TODO: this might not work because AbstractConfigObject inherits
  # from this class, so we can't `require` it from this file
  construct_delayed_merge(Hocon::Impl::AbstractConfigObject.merge_origins(new_stack), new_stack)
end
merged_with_non_object(fallback) click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 229
def merged_with_non_object(fallback)
  require_not_ignoring_fallbacks
  merged_stack_with_non_object([self], fallback)
end
merged_with_object(fallback) click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 224
def merged_with_object(fallback)
  require_not_ignoring_fallbacks
  merged_stack_with_object([self], fallback)
end
merged_with_the_unmergeable(fallback) click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 219
def merged_with_the_unmergeable(fallback)
  require_not_ignoring_fallbacks
  merged_stack_with_the_unmergeable([self], fallback)
end
new_copy(origin) click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 132
def new_copy(origin)
  raise ConfigBugOrBrokenError, "subclasses of AbstractConfigValue should provide their own implementation of `new_copy` (#{self.class})"
end
relativized(prefix) click to toggle source

This is used when including one file in another; the included file is relativized to the path it's included into in the parent file. The point is that if you include a file at foo.bar in the parent, and the included file as a substitution ${a.b.c}, the included substitution now needs to be ${foo.bar.a.b.c} because we resolve substitutions globally only after parsing everything.

@param prefix @return value relativized to the given path or the same value if nothing

to do
# File lib/hocon/impl/abstract_config_value.rb, line 114
def relativized(prefix)
  self
end
render(options = Hocon::ConfigRenderOptions.defaults) click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 338
def render(options = Hocon::ConfigRenderOptions.defaults)
  sb = StringIO.new
  render_to_sb(sb, 0, true, nil, options)
  # We take a substring that ends at sb.pos, because we've been decrementing
  # sb.pos at various points in the code as a means to remove characters from
  # the end of the StringIO
  sb.string[0, sb.pos]
end
render_to_sb(sb, indent, at_root, at_key, options) click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 304
def render_to_sb(sb, indent, at_root, at_key, options)
  if !at_key.nil?
    rendered_key =
        if options.json?
          ConfigImplUtil.render_json_string(at_key)
        else
          ConfigImplUtil.render_string_unquoted_if_possible(at_key)
        end

    sb << rendered_key

    if options.json?
      if options.formatted?
        sb << ": "
      else
        sb << ":"
      end
    else
      case options.key_value_separator
        when :colon
          sb << ": "
        else
          sb << "="
      end      end
  end
  render_value_to_sb(sb, indent, at_root, options)
end
render_value_to_sb(sb, indent, at_root, options) click to toggle source

to be overridden by subclasses

# File lib/hocon/impl/abstract_config_value.rb, line 333
def render_value_to_sb(sb, indent, at_root, options)
  u = unwrapped
  sb << u.to_s
end
require_not_ignoring_fallbacks() click to toggle source

the withFallback() implementation is supposed to avoid calling mergedWith* if we're ignoring fallbacks.

# File lib/hocon/impl/abstract_config_value.rb, line 155
def require_not_ignoring_fallbacks
  if ignores_fallbacks?
    raise ConfigBugOrBrokenError, "method should not have been called with ignoresFallbacks=true #{self.class.name}"
  end
end
resolve_status() click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 62
def resolve_status
  Hocon::Impl::ResolveStatus::RESOLVED
end
resolve_substitutions(context, source) click to toggle source

Called only by ResolveContext.resolve

@param context

state of the current resolve

@param source

where to look up values

@return a new value if there were changes, or this if no changes

# File lib/hocon/impl/abstract_config_value.rb, line 58
def resolve_substitutions(context, source)
  Hocon::Impl::ResolveResult.make(context, self)
end
to_fallback_value() click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 128
def to_fallback_value
  self
end
to_s() click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 284
def to_s
  sb = StringIO.new
  render_to_sb(sb, 0, true, nil, Hocon::ConfigRenderOptions.concise)
  "#{self.class.name.split('::').last}(#{sb.string})"
end
transform_to_string() click to toggle source

toString() is a debugging-oriented string but this is defined to create a string that would parse back to the value in JSON. It only works for primitive values (that would be a single which are auto-converted to strings when concatenating with other strings or by the DefaultTransformer.

# File lib/hocon/impl/abstract_config_value.rb, line 352
def transform_to_string
  nil
end
with_fallback(mergeable) click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 242
def with_fallback(mergeable)
  if ignores_fallbacks?
    self
  else
    other = mergeable.to_fallback_value
    if other.is_a?(Hocon::Impl::Unmergeable)
      merged_with_the_unmergeable(other)
      # TODO: this probably isn't going to work because AbstractConfigObject inherits
      # from this class, so we can't `require` it from this file
    elsif other.is_a?(Hocon::Impl::AbstractConfigObject)
      merged_with_object(other)
    else
      merged_with_non_object(other)
    end
  end
end
with_fallbacks_ignored() click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 145
def with_fallbacks_ignored
  if ignores_fallbacks?
    self
  else
    raise ConfigBugOrBrokenError, "value class doesn't implement forced fallback-ignoring #{self}"
  end
end
with_origin(origin) click to toggle source
# File lib/hocon/impl/abstract_config_value.rb, line 234
def with_origin(origin)
  if @origin.equal?(origin)
    self
  else
    new_copy(origin)
  end
end