@@ -144,57 +144,40 @@ public static void resolveMeasurementPeriodIntoParameters(
144144 parametersMap .put (MeasureConstants .MEASUREMENT_PERIOD_PARAMETER_NAME , validatedPeriod );
145145 }
146146 } else {
147- resolveDefaultMeasurementPeriodWithLibraryStack (
148- context , libraryIdentifiers , firstLibraryId , measureUrls , parametersMap );
147+ resolveDefaultMeasurementPeriod (context , firstLibraryId , parametersMap );
149148 }
150149 }
151150
152151 /**
153- * Resolve the CQL-default measurement period by pushing libraries onto the CQL engine stack,
154- * evaluating the parameter default, UTC-cloning the result, and popping the libraries.
155- * <p/>
156- * <b>Why the push/pop ceremony is required:</b>
157- * <p/>
158- * The CQL engine's {@code visitExpression()} — used internally by {@code visitParameterDef()} to
159- * evaluate a parameter's {@code default} expression — requires {@code state.getCurrentLibrary()}
160- * to be non-null. The library stack is accessed in two places during expression evaluation:
161- * <ol>
162- * <li>Error handling ({@code EvaluationVisitor.kt}) — building source backtraces on exception</li>
163- * <li>Coverage reporting ({@code State.kt}) — marking elements as visited</li>
164- * </ol>
165- * If no library is on the stack, these paths throw a {@code NullPointerException}. There is
166- * currently no CQL engine API to evaluate a parameter default without a library on the stack.
167- * <p/>
168- * <b>To remove this workaround:</b> The CQL engine needs a dedicated API such as
169- * {@code CqlEngine.resolveParameterDefault(VersionedIdentifier, String)} that internally
170- * manages the library stack, so callers don't need to push/pop libraries themselves.
152+ * Resolve the CQL-default measurement period using the CQL engine's
153+ * {@code resolveParameterDefault()} API, UTC-clone it, and add it to the parameters map.
171154 *
172- * @deprecated This method exists only because the CQL engine lacks a clean API for resolving
173- * parameter defaults. Replace with {@code CqlEngine.resolveParameterDefault()} once it
174- * is available in the CQL engine.
155+ * @param context CQL engine context
156+ * @param firstLibraryId the first library identifier to resolve the parameter against
157+ * @param parametersMap mutable parameters map to add the measurement period to
175158 */
176- @ Deprecated (forRemoval = true )
177- private static void resolveDefaultMeasurementPeriodWithLibraryStack (
178- CqlEngine context ,
179- List <VersionedIdentifier > libraryIdentifiers ,
180- VersionedIdentifier firstLibraryId ,
181- List <String > measureUrls ,
182- Map <String , Object > parametersMap ) {
183- var compiledLibraries = LibraryInitHandler .initLibraries (context , libraryIdentifiers );
184- try {
185- var elmLibrary = compiledLibraries .get (0 ).getLibrary ();
186- if (elmLibrary == null ) {
187- throw new InternalErrorException (
188- "Compiled library has no ELM content for identifier: %s, measure URLs: %s"
189- .formatted (firstLibraryId .getId (), measureUrls ));
190- }
191- var defaultPeriod = resolveAndCloneDefaultMeasurementPeriod (context , elmLibrary );
192- if (defaultPeriod != null ) {
193- parametersMap .put (MeasureConstants .MEASUREMENT_PERIOD_PARAMETER_NAME , defaultPeriod );
194- }
195- } finally {
196- LibraryInitHandler .popLibraries (context , compiledLibraries );
159+ private static void resolveDefaultMeasurementPeriod (
160+ CqlEngine context , VersionedIdentifier firstLibraryId , Map <String , Object > parametersMap ) {
161+ // Pre-check: resolve the ELM library and verify the Measurement Period parameter exists.
162+ // If the library can't be resolved (e.g., missing CQL/ELM content), the exception propagates.
163+ var elmLibrary = context .getEnvironment ().resolveLibrary (firstLibraryId );
164+ if (elmLibrary == null || findMeasurementPeriodParameterDef (elmLibrary ) == null ) {
165+ return ;
166+ }
167+
168+ var result =
169+ context .resolveParameterDefault (firstLibraryId , MeasureConstants .MEASUREMENT_PERIOD_PARAMETER_NAME );
170+ if (result == null ) {
171+ return ;
197172 }
173+
174+ if (!(result instanceof Interval defaultPeriod )) {
175+ throw new InternalErrorException (
176+ "\" Measurement Period\" default resolved to %s instead of Interval for library: %s"
177+ .formatted (result .getClass ().getSimpleName (), firstLibraryId .getId ()));
178+ }
179+
180+ parametersMap .put (MeasureConstants .MEASUREMENT_PERIOD_PARAMETER_NAME , cloneIntervalWithUtc (defaultPeriod ));
198181 }
199182
200183 /**
@@ -239,38 +222,6 @@ public static Interval validateAndConvertMeasurementPeriod(
239222 return convertInterval (measurementPeriod , targetType , measureUrls );
240223 }
241224
242- /**
243- * Resolve the CQL default measurement period, UTC-clone it, and return it.
244- * <p/>
245- * Uses the deprecated {@code CqlEngine.getEvaluationVisitor()} because no non-deprecated
246- * CQL API exists for evaluating parameter defaults. When the CQL engine exposes a stable API
247- * for this purpose, replace this method.
248- *
249- * @param context CQL engine with library on the stack
250- * @param elmLibrary the ELM library containing the parameter definition
251- * @return the UTC-cloned default measurement period, or null if no default is defined
252- */
253- @ SuppressWarnings ({"deprecation" , "removal" })
254- @ Nullable
255- public static Interval resolveAndCloneDefaultMeasurementPeriod (CqlEngine context , Library elmLibrary ) {
256- ParameterDef pd = findMeasurementPeriodParameterDef (elmLibrary );
257- if (pd == null || pd .getDefault () == null ) {
258- return null ;
259- }
260- var libraryId = Optional .ofNullable (elmLibrary .getIdentifier ())
261- .map (VersionedIdentifier ::getId )
262- .orElse ("unknown" );
263- var evaluationVisitor = context .getEvaluationVisitor ();
264- var result = evaluationVisitor .visitParameterDef (pd , context .getState ());
265- if (!(result instanceof Interval defaultPeriod )) {
266- throw new InternalErrorException (
267- "\" Measurement Period\" default resolved to %s instead of Interval for library: %s"
268- .formatted (
269- result == null ? "null" : result .getClass ().getSimpleName (), libraryId ));
270- }
271- return cloneIntervalWithUtc (defaultPeriod );
272- }
273-
274225 /**
275226 * Find the "Measurement Period" parameter definition in a given ELM library.
276227 * Does not require CQL engine state.
0 commit comments