File: config_reference.rb

package info (click to toggle)
ruby-hocon 1.4.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 768 kB
  • sloc: ruby: 7,903; makefile: 4
file content (145 lines) | stat: -rw-r--r-- 4,225 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# encoding: utf-8

require_relative '../../hocon'
require_relative '../../hocon/impl'
require_relative '../../hocon/impl/abstract_config_value'

class Hocon::Impl::ConfigReference
  include Hocon::Impl::Unmergeable
  include Hocon::Impl::AbstractConfigValue

  # Require these lazily, to avoid circular dependencies
  require_relative '../../hocon/impl/resolve_source'
  require_relative '../../hocon/impl/resolve_result'


  NotPossibleToResolve = Hocon::Impl::AbstractConfigValue::NotPossibleToResolve
  UnresolvedSubstitutionError = Hocon::ConfigError::UnresolvedSubstitutionError

  attr_reader :expr, :prefix_length

  def initialize(origin, expr, prefix_length = 0)
    super(origin)
    @expr = expr
    @prefix_length = prefix_length
  end

  def unmerged_values
    [self]
  end

  # ConfigReference should be a firewall against NotPossibleToResolve going
  # further up the stack; it should convert everything to ConfigException.
  # This way it 's impossible for NotPossibleToResolve to "escape" since
  # any failure to resolve has to start with a ConfigReference.
  def resolve_substitutions(context, source)
    new_context = context.add_cycle_marker(self)
    begin
      result_with_path = source.lookup_subst(new_context, @expr, @prefix_length)
      new_context = result_with_path.result.context

      if result_with_path.result.value != nil
        if Hocon::Impl::ConfigImpl.trace_substitution_enabled
          Hocon::Impl::ConfigImpl.trace(
              "recursively resolving #{result_with_path} which was the resolution of #{expr} against #{source}",
              context.depth)
        end

        recursive_resolve_source = Hocon::Impl::ResolveSource.new(
            result_with_path.path_from_root.last, result_with_path.path_from_root)

        if Hocon::Impl::ConfigImpl.trace_substitution_enabled
          Hocon::Impl::ConfigImpl.trace("will recursively resolve against #{recursive_resolve_source}", context.depth)
        end

        result = new_context.resolve(result_with_path.result.value,
                                     recursive_resolve_source)
        v = result.value
        new_context = result.context
      else
        v = nil
      end
    rescue NotPossibleToResolve => e
      if Hocon::Impl::ConfigImpl.trace_substitution_enabled
        Hocon::Impl::ConfigImpl.trace(
            "not possible to resolve #{expr}, cycle involved: #{e.trace_string}", new_context.depth)
      end
      if @expr.optional
        v = nil
      else
        raise UnresolvedSubstitutionError.new(
                  origin,
                  "#{@expr} was part of a cycle of substitutions involving #{e.trace_string}", e)
      end
    end

    if v == nil && !@expr.optional
      if new_context.options.allow_unresolved
        ResolveResult.make(new_context.remove_cycle_marker(self), self)
      else
        raise UnresolvedSubstitutionError.new(origin, @expr.to_s)
      end
    else
      Hocon::Impl::ResolveResult.make(new_context.remove_cycle_marker(self), v)
    end

  end

  def value_type
    raise not_resolved
  end

  def unwrapped
    raise not_resolved
  end

  def new_copy(new_origin)
    Hocon::Impl::ConfigReference.new(new_origin, @expr, @prefix_length)
  end

  def ignores_fallbacks?
    false
  end

  def resolve_status
    Hocon::Impl::ResolveStatus::UNRESOLVED
  end

  def relativized(prefix)
    new_expr = @expr.change_path(@expr.path.prepend(prefix))

    Hocon::Impl::ConfigReference.new(origin, new_expr, @prefix_length + prefix.length)
  end

  def can_equal(other)
    other.is_a? Hocon::Impl::ConfigReference
  end

  def ==(other)
    # note that "origin" is deliberately NOT part of equality
    if other.is_a? Hocon::Impl::ConfigReference
      can_equal(other) && @expr == other.expr
    end
  end

  def hash
    # note that "origin" is deliberately NOT part of equality
    @expr.hash
  end

  def render_value_to_sb(sb, indent, at_root, options)
    sb << @expr.to_s
  end

  def expression
    @expr
  end

  private

  def not_resolved
    error_message = "need to Config#resolve, see the API docs for Config#resolve; substitution not resolved: #{self}"
    Hocon::ConfigError::ConfigNotResolvedError.new(error_message, nil)
  end

end