View Javadoc
1   /*
2    * Themis: Java Project Framework
3    * Copyright 2012-2026. Tony Washer
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
6    * use this file except in compliance with the License.  You may obtain a copy
7    * of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
14   * License for the specific language governing permissions and limitations under
15   * the License.
16   */
17  package io.github.tonywasher.joceanus.themis.lethe.analysis;
18  
19  import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
20  import io.github.tonywasher.joceanus.themis.lethe.analysis.ThemisAnalysisFile.ThemisAnalysisObject;
21  import io.github.tonywasher.joceanus.themis.lethe.analysis.ThemisAnalysisGeneric.ThemisAnalysisGenericBase;
22  
23  import java.util.ArrayDeque;
24  import java.util.ArrayList;
25  import java.util.Deque;
26  import java.util.List;
27  
28  /**
29   * Enum representation.
30   */
31  public class ThemisAnalysisEnum
32          implements ThemisAnalysisObject {
33      /**
34       * The short name of the class.
35       */
36      private final String theShortName;
37  
38      /**
39       * The full name of the class.
40       */
41      private final String theFullName;
42  
43      /**
44       * The ancestors.
45       */
46      private final List<ThemisAnalysisReference> theAncestors;
47  
48      /**
49       * The contents.
50       */
51      private final Deque<ThemisAnalysisElement> theContents;
52  
53      /**
54       * The dataMap.
55       */
56      private final ThemisAnalysisDataMap theDataMap;
57  
58      /**
59       * The values.
60       */
61      private final List<String> theValues;
62  
63      /**
64       * The number of lines.
65       */
66      private int theNumLines;
67  
68      /**
69       * The properties.
70       */
71      private ThemisAnalysisProperties theProperties;
72  
73      /**
74       * Constructor.
75       *
76       * @param pParser the parser
77       * @param pLine   the initial enum line
78       * @throws OceanusException on error
79       */
80      ThemisAnalysisEnum(final ThemisAnalysisParser pParser,
81                         final ThemisAnalysisLine pLine) throws OceanusException {
82          /* Store parameters */
83          theShortName = pLine.stripNextToken();
84          theProperties = pLine.getProperties();
85          theValues = new ArrayList<>();
86          final ThemisAnalysisContainer myParent = pParser.getParent();
87          final ThemisAnalysisDataMap myParentDataMap = myParent.getDataMap();
88          theDataMap = new ThemisAnalysisDataMap(myParentDataMap);
89  
90          /* If this is a local enum */
91          if (!(myParent instanceof ThemisAnalysisObject)
92                  && (!(myParent instanceof ThemisAnalysisFile))) {
93              final int myId = myParentDataMap.getLocalId(theShortName);
94              theFullName = myParent.determineFullChildName(myId + theShortName);
95  
96              /* else handle standard name */
97          } else {
98              theFullName = myParent.determineFullChildName(theShortName);
99          }
100 
101         /* Handle generic variables */
102         ThemisAnalysisLine myLine = pLine;
103         if (ThemisAnalysisGeneric.isGeneric(pLine)) {
104             /* Declare them to the properties */
105             theProperties = theProperties.setGenericVariables(new ThemisAnalysisGenericBase(pParser, myLine));
106             myLine = (ThemisAnalysisLine) pParser.popNextLine();
107         }
108 
109         /* declare the enum */
110         theDataMap.declareObject(this);
111 
112         /* Parse the headers */
113         final Deque<ThemisAnalysisElement> myHeaders = ThemisAnalysisBuilder.parseHeaders(pParser, myLine);
114         theNumLines = myHeaders.size() + 1;
115 
116         /* Parse the body */
117         final Deque<ThemisAnalysisElement> myLines = ThemisAnalysisBuilder.processBody(pParser);
118 
119         /* Create a parser */
120         theContents = new ArrayDeque<>();
121         final ThemisAnalysisParser myParser = new ThemisAnalysisParser(myLines, theContents, this);
122 
123         /* Resolve the generics */
124         theProperties.resolveGeneric(myParser);
125 
126         /* Parse the ancestors and lines */
127         theAncestors = myParser.parseAncestors(myHeaders);
128         initialProcessingPass(myParser);
129     }
130 
131     /**
132      * perform initial processing pass.
133      *
134      * @param pParser the parser
135      * @throws OceanusException on error
136      */
137     void initialProcessingPass(final ThemisAnalysisParser pParser) throws OceanusException {
138         /* we are still processing Enums */
139         boolean look4Enum = true;
140 
141         /* Loop through the lines */
142         while (pParser.hasLines()) {
143             /* Access next line */
144             final ThemisAnalysisLine myLine = (ThemisAnalysisLine) pParser.popNextLine();
145 
146             /* Process comments and blanks */
147             boolean processed = pParser.processCommentsAndBlanks(myLine);
148 
149             /* Process enumValue */
150             if (!processed && look4Enum) {
151                 look4Enum = processEnumValue(pParser, myLine);
152                 processed = true;
153             }
154 
155             /* Process embedded classes/languageConstructs */
156             if (!processed) {
157                 processed = pParser.processClass(myLine)
158                         || pParser.processLanguage(myLine)
159                         || pParser.processBlocks(myLine);
160             }
161 
162             /* If we haven't processed yet */
163             if (!processed) {
164                 /* Just add the line to contents at present */
165                 theContents.add(myLine);
166             }
167         }
168     }
169 
170     /**
171      * process the enumValue.
172      *
173      * @param pParser the parser
174      * @param pLine   the line
175      * @return continue to look for eNums true/false
176      * @throws OceanusException on error
177      */
178     private boolean processEnumValue(final ThemisAnalysisParser pParser,
179                                      final ThemisAnalysisLine pLine) throws OceanusException {
180         /* Access the token */
181         ThemisAnalysisLine myLine = pLine;
182         final String myToken = myLine.stripNextToken();
183         theNumLines++;
184         if (myLine.startsWithChar(ThemisAnalysisChar.PARENTHESIS_OPEN)) {
185             final ThemisAnalysisScanner myScanner = new ThemisAnalysisScanner(pParser);
186             final Deque<ThemisAnalysisElement> myDef = myScanner.scanForParenthesis(myLine);
187             myLine = (ThemisAnalysisLine) pParser.popNextLine();
188             theNumLines += myDef.size() - 1;
189         }
190         theValues.add(myToken);
191         return myLine.endsWithChar(ThemisAnalysisChar.COMMA);
192     }
193 
194     @Override
195     public String getShortName() {
196         return theShortName;
197     }
198 
199     @Override
200     public String getFullName() {
201         return theFullName;
202     }
203 
204     @Override
205     public ThemisAnalysisDataMap getDataMap() {
206         return theDataMap;
207     }
208 
209     @Override
210     public ThemisAnalysisProperties getProperties() {
211         return theProperties;
212     }
213 
214     @Override
215     public Deque<ThemisAnalysisElement> getContents() {
216         return theContents;
217     }
218 
219     @Override
220     public ThemisAnalysisContainer getParent() {
221         return this;
222     }
223 
224     @Override
225     public List<ThemisAnalysisReference> getAncestors() {
226         return theAncestors;
227     }
228 
229     @Override
230     public int getNumLines() {
231         return theNumLines;
232     }
233 
234     /**
235      * Obtain the number of enums.
236      *
237      * @return the number of enums
238      */
239     public int getNumEnums() {
240         return theValues.size();
241     }
242 
243     @Override
244     public String toString() {
245         return getShortName();
246     }
247 }