class Hocon::Impl::Parseable
Internal implementation detail, not ABI stable, do not touch. For use only by the {@link com.typesafe.config} package. The point of this class is to avoid “propagating” each overload on “thing which can be parsed” through multiple interfaces. Most interfaces can have just one overload that takes a Parseable
. Also it's used as an abstract “resource handle” in the ConfigIncluder interface.
Constants
- MAX_INCLUDE_DEPTH
Public Class Methods
force_parsed_to_object(value)
click to toggle source
# File lib/hocon/impl/parseable.rb, line 122 def self.force_parsed_to_object(value) if value.is_a? Hocon::Impl::AbstractConfigObject value else raise Hocon::ConfigError::ConfigWrongTypeError.with_expected_actual(value.origin, "", "object at file root", Hocon::ConfigValueType.value_type_name(value.value_type)) end end
new()
click to toggle source
# File lib/hocon/impl/parseable.rb, line 45 def initialize end
new_file(file_path, options)
click to toggle source
# File lib/hocon/impl/parseable.rb, line 464 def self.new_file(file_path, options) ParseableFile.new(file_path, options) end
new_not_found(what_not_found, message, options)
click to toggle source
# File lib/hocon/impl/parseable.rb, line 348 def self.new_not_found(what_not_found, message, options) ParseableNotFound.new(what_not_found, message, options) end
new_resources(resource, options)
click to toggle source
# File lib/hocon/impl/parseable.rb, line 544 def self.new_resources(resource, options) ParseableResources.new(resource, options) end
new_string(string, options)
click to toggle source
# File lib/hocon/impl/parseable.rb, line 390 def self.new_string(string, options) ParseableString.new(string, options) end
relative_to(file, filename)
click to toggle source
NOTE: skipping `relativeTo(URL, String)` because we're not supporting URLs for now
# File lib/hocon/impl/parseable.rb, line 313 def self.relative_to(file, filename) child = Pathname.new(filename) file = Pathname.new(file) if child.absolute? nil end parent = file.parent if parent.nil? nil else File.join(parent, filename) end end
syntax_from_extension(name)
click to toggle source
# File lib/hocon/impl/parseable.rb, line 299 def self.syntax_from_extension(name) if name.end_with?(".json") Hocon::ConfigSyntax::JSON elsif name.end_with?(".conf") Hocon::ConfigSyntax::CONF else # Skipping PROPERTIES because we can't really support that in ruby nil end end
trace(message)
click to toggle source
# File lib/hocon/impl/parseable.rb, line 92 def self.trace(message) if Hocon::Impl::ConfigImpl.trace_loads_enabled Hocon::Impl::ConfigImpl.trace(message) end end
Public Instance Methods
content_type()
click to toggle source
# File lib/hocon/impl/parseable.rb, line 102 def content_type nil end
create_origin()
click to toggle source
# File lib/hocon/impl/parseable.rb, line 287 def create_origin raise Hocon::ConfigError::ConfigBugOrBrokenError, "subclasses of `Parseable` must implement `create_origin` (#{self.class})" end
custom_reader()
click to toggle source
the general idea is that any work should be in here, not in the constructor, so that exceptions are thrown from the public parse() function and not from the creation of the Parseable. Essentially this is a lazy field. The parser should close the reader when it's done with it.
{//}# ALSO, IMPORTANT: if the file or URL is not found, this must throw. {//}# to support the “allow missing” feature.
# File lib/hocon/impl/parseable.rb, line 84 def custom_reader raise Hocon::ConfigError::ConfigBugOrBrokenError, "subclasses of `Parseable` must implement `custom_reader` (#{self.class})" end
fixup_options(base_options)
click to toggle source
# File lib/hocon/impl/parseable.rb, line 49 def fixup_options(base_options) syntax = base_options.syntax if !syntax syntax = guess_syntax end if !syntax syntax = Hocon::ConfigSyntax::CONF end modified = base_options.set_syntax(syntax) # make sure the app-provided includer falls back to default modified = modified.append_includer(Hocon::Impl::ConfigImpl.default_includer) # make sure the app-provided includer is complete modified = modified.set_includer(Hocon::Impl::SimpleIncluder.make_full(modified.includer)) modified end
guess_syntax()
click to toggle source
# File lib/hocon/impl/parseable.rb, line 98 def guess_syntax nil end
include_context()
click to toggle source
# File lib/hocon/impl/parseable.rb, line 118 def include_context @include_context end
options()
click to toggle source
# File lib/hocon/impl/parseable.rb, line 291 def options @initial_options end
origin()
click to toggle source
# File lib/hocon/impl/parseable.rb, line 283 def origin @initial_origin end
parse(base_options = nil)
click to toggle source
# File lib/hocon/impl/parseable.rb, line 133 def parse(base_options = nil) if (base_options.nil?) base_options = options end stack = @@parse_stack if stack.length >= MAX_INCLUDE_DEPTH raise Hocon::ConfigError::ConfigParseError.new(@initial_origin, "include statements nested more than #{MAX_INCLUDE_DEPTH} times, " + "you probably have a cycle in your includes. Trace: #{stack}", nil) end # Push into beginning of stack stack.unshift(self) begin self.class.force_parsed_to_object(parse_value(base_options)) ensure # Pop from beginning of stack stack.shift end end
parse_config_document()
click to toggle source
# File lib/hocon/impl/parseable.rb, line 279 def parse_config_document parse_document(options) end
parse_document(base_options = nil)
click to toggle source
# File lib/hocon/impl/parseable.rb, line 189 def parse_document(base_options = nil) if base_options.nil? base_options = options end # note that we are NOT using our "initialOptions", # but using the ones from the passed-in options. The idea is that # callers can get our original options and then parse with different # ones if they want. options = fixup_options(base_options) # passed-in option can override origin origin = nil if ! options.origin_description.nil? origin = Hocon::Impl::SimpleConfigOrigin.new_simple(options.origin_description) else origin = @initial_origin end parse_document_from_origin(origin, options) end
parse_document_from_origin(origin, final_options)
click to toggle source
# File lib/hocon/impl/parseable.rb, line 210 def parse_document_from_origin(origin, final_options) begin raw_parse_document(origin, final_options) rescue IOError => e if final_options.allow_missing? Hocon::Impl::SimpleConfigDocument.new( Hocon::Impl::ConfigNodeObject.new([]), final_options) else self.class.trace("exception loading #{origin.description}: #{e.class}: #{e.message}") raise ConfigIOError.new(origin, "#{e.class.name}: #{e.message}", e) end end end
parse_value(base_options = nil)
click to toggle source
# File lib/hocon/impl/parseable.rb, line 155 def parse_value(base_options = nil) if base_options.nil? base_options = options end # note that we are NOT using our "initialOptions", # but using the ones from the passed-in options. The idea is that # callers can get our original options and then parse with different # ones if they want. options = fixup_options(base_options) # passed-in options can override origin origin = if options.origin_description Hocon::Impl::SimpleConfigOrigin.new_simple(options.origin_description) else @initial_origin end parse_value_from_origin(origin, options) end
parse_value_from_origin(origin, final_options)
click to toggle source
# File lib/hocon/impl/parseable.rb, line 176 def parse_value_from_origin(origin, final_options) begin raw_parse_value(origin, final_options) rescue IOError => e if final_options.allow_missing? Hocon::Impl::SimpleConfigObject.empty_missing(origin) else self.class.trace("exception loading #{origin.description}: #{e.class}: #{e.message}") raise Hocon::ConfigError::ConfigIOError.new(origin, "#{e.class.name}: #{e.message}", e) end end end
post_construct(base_options)
click to toggle source
# File lib/hocon/impl/parseable.rb, line 67 def post_construct(base_options) @initial_options = fixup_options(base_options) @include_context = Hocon::Impl::SimpleIncludeContext.new(self) if @initial_options.origin_description @initial_origin = Hocon::Impl::SimpleConfigOrigin.new_simple(@initial_options.origin_description) else @initial_origin = create_origin end end
raw_parse_document(origin, final_options)
click to toggle source
# File lib/hocon/impl/parseable.rb, line 253 def raw_parse_document(origin, final_options) reader = reader(final_options) content_type = content_type() options_with_content_type = nil if !(content_type.nil?) if Hocon::Impl::ConfigImpl.trace_loads_enabled && (! final_options.get_syntax.nil?) self.class.trace("Overriding syntax #{final_options.get_syntax} with Content-Type which specified #{content-type}") end options_with_content_type = final_options.set_syntax(content_type) else options_with_content_type = final_options end reader.open { |io| raw_parse_document_from_io(io, origin, options_with_content_type) } end
raw_parse_document_from_io(reader, origin, final_options)
click to toggle source
# File lib/hocon/impl/parseable.rb, line 272 def raw_parse_document_from_io(reader, origin, final_options) tokens = Hocon::Impl::Tokenizer.tokenize(origin, reader, final_options.syntax) Hocon::Impl::SimpleConfigDocument.new( Hocon::Impl::ConfigDocumentParser.parse(tokens, origin, final_options), final_options) end
raw_parse_value(origin, final_options)
click to toggle source
this is parseValue without post-processing the IOException or handling options.getAllowMissing()
# File lib/hocon/impl/parseable.rb, line 226 def raw_parse_value(origin, final_options) reader = reader(final_options) # after reader() we will have loaded the Content-Type content_type = content_type() options_with_content_type = nil if !(content_type.nil?) if Hocon::Impl::ConfigImpl.trace_loads_enabled && (! final_options.get_syntax.nil?) self.class.trace("Overriding syntax #{final_options.get_syntax} with Content-Type which specified #{content-type}") end options_with_content_type = final_options.set_syntax(content_type) else options_with_content_type = final_options end reader.open { |io| raw_parse_value_from_io(io, origin, options_with_content_type) } end
raw_parse_value_from_io(io, origin, final_options)
click to toggle source
# File lib/hocon/impl/parseable.rb, line 247 def raw_parse_value_from_io(io, origin, final_options) tokens = Hocon::Impl::Tokenizer.tokenize(origin, io, final_options.syntax) document = Hocon::Impl::ConfigDocumentParser.parse(tokens, origin, final_options) Hocon::Impl::ConfigParser.parse(document, origin, final_options, include_context) end
reader(options)
click to toggle source
# File lib/hocon/impl/parseable.rb, line 88 def reader(options) custom_reader end
relative_to(filename)
click to toggle source
# File lib/hocon/impl/parseable.rb, line 106 def relative_to(filename) # fall back to classpath; we treat the "filename" as absolute # (don't add a package name in front), # if it starts with "/" then remove the "/", for consistency # with ParseableResources.relativeTo resource = filename if filename.start_with?("/") resource = filename.slice(1) end self.class.new_resources(resource, options.set_origin_description(nil)) end
to_s()
click to toggle source
# File lib/hocon/impl/parseable.rb, line 295 def to_s self.class.name.split('::').last end