code: @Nonnull
      <M extends PMessage<M, F>, F extends PField> Pair<M, Set<String>> parseConfig(@Nonnull Path configFile, @Nullable M parent)
              throws ProvidenceConfigException {
          try {
              configFile = canonicalFileLocation(configFile);
          } catch (IOException e) {
              throw new ProvidenceConfigException(e, "Unable to resolve config file " + configFile)
                      .setFile(configFile.getFileName()
                                         .toString());
          }
          Pair<M, Set<String>> result = checkAndParseInternal(configFile, parent);
          if (result == null) {
              throw new ProvidenceConfigException("No config: " + configFile.toString())
                      .setFile(configFile.getFileName()
                                         .toString());
          }
          return result;
      }
docs: Parse a providence config into a message.
  
  @param configFile The config file to be parsed.
  @param parent The parent config message.
  @param <M> The config message type.
  @param <F> The config field type.
  @return Pair of parsed config and set of included file paths.
  @throws ProvidenceConfigException If parsing failed.