<commit_before>/**
 *   Copyright (C) 2011-2012 Typesafe Inc. <http://typesafe.com>
 */
package com.typesafe.config;

import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * An immutable map from config paths to config values. Paths are dot-separated
 * expressions such as <code>foo.bar.baz</code>. Values are as in JSON
 * (booleans, strings, numbers, lists, or objects), represented by
 * {@link ConfigValue} instances. Values accessed through the
 * <code>Config</code> interface are never null.
 * 
 * <p>
 * {@code Config} is an immutable object and thus safe to use from multiple
 * threads. There's never a need for "defensive copies."
 * 
 * <p>
 * Fundamental operations on a {@code Config} include getting configuration
 * values, <em>resolving</em> substitutions with {@link Config#resolve()}, and
 * merging configs using {@link Config#withFallback(ConfigMergeable)}.
 * 
 * <p>
 * All operations return a new immutable {@code Config} rather than modifying
 * the original instance.
 * 
 * <p>
 * <strong>Examples</strong>
 * 
 * <p>
 * You can find an example app and library <a
 * href="https://github.com/typesafehub/config/tree/master/examples">on
 * GitHub</a>. Also be sure to read the <a
 * href="package-summary.html#package_description">package overview</a> which
 * describes the big picture as shown in those examples.
 * 
 * <p>
 * <strong>Paths, keys, and Config vs. ConfigObject</strong>
 * 
 * <p>
 * <code>Config</code> is a view onto a tree of {@link ConfigObject}; the
 * corresponding object tree can be found through {@link Config#root()}.
 * <code>ConfigObject</code> is a map from config <em>keys</em>, rather than
 * paths, to config values. Think of <code>ConfigObject</code> as a JSON object
 * and <code>Config</code> as a configuration API.
 * 
 * <p>
 * The API tries to consistently use the terms "key" and "path." A key is a key
 * in a JSON object; it's just a string that's the key in a map. A "path" is a
 * parseable expression with a syntax and it refers to a series of keys. Path
 * expressions are described in the <a
 * href="https://github.com/typesafehub/config/blob/master/HOCON.md">spec for
 * Human-Optimized Config Object Notation</a>. In brief, a path is
 * period-separated so "a.b.c" looks for key c in object b in object a in the
 * root object. Sometimes double quotes are needed around special characters in
 * path expressions.
 * 
 * <p>
 * The API for a {@code Config} is in terms of path expressions, while the API
 * for a {@code ConfigObject} is in terms of keys. Conceptually, {@code Config}
 * is a one-level map from <em>paths</em> to values, while a
 * {@code ConfigObject} is a tree of nested maps from <em>keys</em> to values.
 * 
 * <p>
 * Use {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath} to convert
 * between path expressions and individual path elements (keys).
 * 
 * <p>
 * Another difference between {@code Config} and {@code ConfigObject} is that
 * conceptually, {@code ConfigValue}s with a {@link ConfigValue#valueType()
 * valueType()} of {@link ConfigValueType#NULL NULL} exist in a
 * {@code ConfigObject}, while a {@code Config} treats null values as if they
 * were missing.
 * 
 * <p>
 * <strong>Getting configuration values</strong>
 * 
 * <p>
 * The "getters" on a {@code Config} all work in the same way. They never return
 * null, nor do they return a {@code ConfigValue} with
 * {@link ConfigValue#valueType() valueType()} of {@link ConfigValueType#NULL
 * NULL}. Instead, they throw {@link ConfigException.Missing} if the value is
 * completely absent or set to null. If the value is set to null, a subtype of
 * {@code ConfigException.Missing} called {@link ConfigException.Null} will be
 * thrown. {@link ConfigException.WrongType} will be thrown anytime you ask for
 * a type and the value has an incompatible type. Reasonable type conversions
 * are performed for you though.
 * 
 * <p>
 * <strong>Iteration</strong>
 * 
 * <p>
 * If you want to iterate over the contents of a {@code Config}, you can get its
 * {@code ConfigObject} with {@link #root()}, and then iterate over the
 * {@code ConfigObject} (which implements <code>java.util.Map</code>). Or, you
 * can use {@link #entrySet()} which recurses the object tree for you and builds
 * up a <code>Set</code> of all path-value pairs where the value is not null.<commit_msg>Mention getIsNull and hasPathOrNull as exceptions to "Config hides null" docs<commit_after>/**
 *   Copyright (C) 2011-2012 Typesafe Inc. <http://typesafe.com>
 */
package com.typesafe.config;

import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * An immutable map from config paths to config values. Paths are dot-separated
 * expressions such as <code>foo.bar.baz</code>. Values are as in JSON
 * (booleans, strings, numbers, lists, or objects), represented by
 * {@link ConfigValue} instances. Values accessed through the
 * <code>Config</code> interface are never null.
 * 
 * <p>
 * {@code Config} is an immutable object and thus safe to use from multiple
 * threads. There's never a need for "defensive copies."
 * 
 * <p>
 * Fundamental operations on a {@code Config} include getting configuration
 * values, <em>resolving</em> substitutions with {@link Config#resolve()}, and
 * merging configs using {@link Config#withFallback(ConfigMergeable)}.
 * 
 * <p>
 * All operations return a new immutable {@code Config} rather than modifying
 * the original instance.
 * 
 * <p>
 * <strong>Examples</strong>
 * 
 * <p>
 * You can find an example app and library <a
 * href="https://github.com/typesafehub/config/tree/master/examples">on
 * GitHub</a>. Also be sure to read the <a
 * href="package-summary.html#package_description">package overview</a> which
 * describes the big picture as shown in those examples.
 * 
 * <p>
 * <strong>Paths, keys, and Config vs. ConfigObject</strong>
 * 
 * <p>
 * <code>Config</code> is a view onto a tree of {@link ConfigObject}; the
 * corresponding object tree can be found through {@link Config#root()}.
 * <code>ConfigObject</code> is a map from config <em>keys</em>, rather than
 * paths, to config values. Think of <code>ConfigObject</code> as a JSON object
 * and <code>Config</code> as a configuration API.
 * 
 * <p>
 * The API tries to consistently use the terms "key" and "path." A key is a key
 * in a JSON object; it's just a string that's the key in a map. A "path" is a
 * parseable expression with a syntax and it refers to a series of keys. Path
 * expressions are described in the <a
 * href="https://github.com/typesafehub/config/blob/master/HOCON.md">spec for
 * Human-Optimized Config Object Notation</a>. In brief, a path is
 * period-separated so "a.b.c" looks for key c in object b in object a in the
 * root object. Sometimes double quotes are needed around special characters in
 * path expressions.
 * 
 * <p>
 * The API for a {@code Config} is in terms of path expressions, while the API
 * for a {@code ConfigObject} is in terms of keys. Conceptually, {@code Config}
 * is a one-level map from <em>paths</em> to values, while a
 * {@code ConfigObject} is a tree of nested maps from <em>keys</em> to values.
 * 
 * <p>
 * Use {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath} to convert
 * between path expressions and individual path elements (keys).
 * 
 * <p>
 * Another difference between {@code Config} and {@code ConfigObject} is that
 * conceptually, {@code ConfigValue}s with a {@link ConfigValue#valueType()
 * valueType()} of {@link ConfigValueType#NULL NULL} exist in a
 * {@code ConfigObject}, while a {@code Config} treats null values as if they
 * were missing. (With the exception of two methods: {@link Config#hasPathOrNull}
 * and {@link Config#getIsNull} let you detect <code>null</code> values.)
 *
 * <p>
 * <strong>Getting configuration values</strong>
 * 
 * <p>
 * The "getters" on a {@code Config} all work in the same way. They never return
 * null, nor do they return a {@code ConfigValue} with
 * {@link ConfigValue#valueType() valueType()} of {@link ConfigValueType#NULL
 * NULL}. Instead, they throw {@link ConfigException.Missing} if the value is
 * completely absent or set to null. If the value is set to null, a subtype of
 * {@code ConfigException.Missing} called {@link ConfigException.Null} will be
 * thrown. {@link ConfigException.WrongType} will be thrown anytime you ask for
 * a type and the value has an incompatible type. Reasonable type conversions
 * are performed for you though.
 * 
 * <p>
 * <strong>Iteration</strong>
 * 
 * <p>
 * If you want to iterate over the contents of a {@code Config}, you can get its
 * {@code ConfigObject} with {@link #root()}, and then iterate over the
 * {@code ConfigObject} (which implements <code>java.util.Map</code>). Or, you
 * can use {@link #entrySet()} which recurses the object tree for you and builds
 * up a <code>Set</code> of all path-value pairs where the value is not null.
{'fraction_non_alphanumeric': 0.11496028243601059, 'fraction_numerical': 0.00176522506619594, 'mean_word_length': 4.104166666666667, 'pattern_counts': {'":': 0, '<': 113, '<?xml version=': 0, '>': 113, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4327651', 'n_tokens_mistral': 2665, 'n_tokens_neox': 2569, 'n_words': 1153}