ConfigContext.java

  1. /*
  2.  * Copyright 2017 Providence Authors
  3.  *
  4.  * Licensed to the Apache Software Foundation (ASF) under one
  5.  * or more contributor license agreements. See the NOTICE file
  6.  * distributed with this work for additional information
  7.  * regarding copyright ownership. The ASF licenses this file
  8.  * to you under the Apache License, Version 2.0 (the
  9.  * "License"); you may not use this file except in compliance
  10.  * with the License. You may obtain a copy of the License at
  11.  *
  12.  *   http://www.apache.org/licenses/LICENSE-2.0
  13.  *
  14.  * Unless required by applicable law or agreed to in writing,
  15.  * software distributed under the License is distributed on an
  16.  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  17.  * KIND, either express or implied. See the License for the
  18.  * specific language governing permissions and limitations
  19.  * under the License.
  20.  */
  21. package net.morimekta.providence.config.parser;

  22. import net.morimekta.providence.PMessage;

  23. import java.util.HashMap;
  24. import java.util.HashSet;
  25. import java.util.Map;
  26. import java.util.Set;

  27. import static net.morimekta.providence.config.parser.ConfigUtil.RESERVED_WORDS;

  28. /**
  29.  * Context object related to a providence file being parsed. Takes care of
  30.  * knowing about includes and registered references.
  31.  */
  32. class ConfigContext {
  33.     private final Set<String>                  includeAliases;
  34.     private final Map<String, Object>          references;
  35.     private final Map<String, ConfigException> referenceExceptions;

  36.     ConfigContext() {
  37.         this.references = new HashMap<>();
  38.         this.referenceExceptions = new HashMap<>();
  39.         this.includeAliases = new HashSet<>();
  40.     }

  41.     boolean containsReference(String name) {
  42.         return referenceExceptions.containsKey(name) ||
  43.                references.containsKey(name);
  44.     }

  45.     void setInclude(String alias, PMessage include) {
  46.         references.put(alias, include);
  47.         includeAliases.add(alias);
  48.     }

  49.     String initReference(ConfigToken token) throws ConfigException {
  50.         String reference = token.toString();
  51.         if (RESERVED_WORDS.contains(reference)) {
  52.             throw new ConfigException(token, "Trying to assign reference id '%s', which is reserved.", reference);
  53.         }

  54.         ConfigException ex = referenceExceptions.get(reference);
  55.         if (ex != null) {
  56.             if (references.containsKey(reference)) {
  57.                 throw new ConfigException(token,
  58.                                           "Trying to reassign reference '%s', original at line %d",
  59.                                           reference,
  60.                                           ex.getLineNo())
  61.                         .initCause(ex);
  62.             }
  63.             throw new ConfigException(token,
  64.                                       "Trying to reassign reference '%s' while calculating it's value, original at line %d",
  65.                                       reference,
  66.                                       ex.getLineNo())
  67.                     .initCause(ex);
  68.         } else if (includeAliases.contains(reference)) {
  69.             throw new ConfigException(token,
  70.                                       "Trying to reassign include alias '%s' to reference.",
  71.                                       reference);
  72.         }

  73.         referenceExceptions.put(reference, new ConfigException(token, "Original reference"));
  74.         return reference;
  75.     }

  76.     Object setReference(String reference, Object value) {
  77.         if (reference != null) {
  78.             if (!referenceExceptions.containsKey(reference)) {
  79.                 throw new RuntimeException("Reference '" + reference + "' not initialised");
  80.             }
  81.             references.put(reference, value);
  82.         }
  83.         return value;
  84.     }

  85.     Object getReference(String reference, ConfigToken token) throws ConfigException {
  86.         if (RESERVED_WORDS.contains(reference)) {
  87.             return null;
  88.         }
  89.         if (references.containsKey(reference)) {
  90.             return references.get(reference);
  91.         }

  92.         ConfigException ex = referenceExceptions.get(reference);
  93.         if (ex != null) {
  94.             throw new ConfigException(token, "Trying to reference '%s' while it's being defined, original at line %d",
  95.                                       reference, ex.getLineNo());
  96.         }
  97.         throw new ConfigException(token, "No such reference '%s'", reference);
  98.     }
  99. }