1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package dev.metaschema.schemagen;
7   
8   import dev.metaschema.core.configuration.IConfiguration;
9   import dev.metaschema.core.model.IDefinition;
10  import edu.umd.cs.findbugs.annotations.NonNull;
11  
12  /**
13   * A strategy for determining whether a definition should be inlined in the
14   * generated schema or referenced as a separate type definition.
15   */
16  @FunctionalInterface
17  public interface IInlineStrategy {
18    /**
19     * A strategy that never inlines any definition.
20     */
21    @NonNull
22    IInlineStrategy NONE_INLINE = new IInlineStrategy() {
23      @Override
24      public boolean isInline(
25          @NonNull IDefinition definition,
26          @NonNull ModuleIndex metaschemaIndex) {
27        return false;
28      }
29    };
30  
31    /**
32     * A strategy that inlines definitions based on their
33     * {@link IDefinition#isInline()} property.
34     */
35    @NonNull
36    IInlineStrategy DEFINED_AS_INLINE = new IInlineStrategy() {
37      @Override
38      public boolean isInline(
39          @NonNull IDefinition definition,
40          @NonNull ModuleIndex metaschemaIndex) {
41        return definition.isInline();
42      }
43    };
44  
45    /**
46     * A strategy that inlines definitions unless they are used in a choice group.
47     */
48    @NonNull
49    IInlineStrategy CHOICE_NOT_INLINE = new ChoiceNotInlineStrategy();
50  
51    /**
52     * Create a new inline strategy based on the provided configuration.
53     *
54     * @param configuration
55     *          the schema generation configuration
56     * @return the appropriate inline strategy based on the configuration settings
57     */
58    @NonNull
59    static IInlineStrategy newInlineStrategy(@NonNull IConfiguration<SchemaGenerationFeature<?>> configuration) {
60      IInlineStrategy retval;
61      if (configuration.isFeatureEnabled(SchemaGenerationFeature.INLINE_DEFINITIONS)) {
62        if (configuration.isFeatureEnabled(SchemaGenerationFeature.INLINE_CHOICE_DEFINITIONS)) {
63          retval = DEFINED_AS_INLINE;
64        } else {
65          retval = CHOICE_NOT_INLINE;
66        }
67      } else {
68        retval = NONE_INLINE;
69      }
70      return retval;
71    }
72  
73    /**
74     * Determine if the provided definition should be inlined in the generated
75     * schema.
76     *
77     * @param definition
78     *          the definition to check
79     * @param metaschemaIndex
80     *          the module index containing definition usage information
81     * @return {@code true} if the definition should be inlined, {@code false} if it
82     *         should be referenced as a separate type
83     */
84    boolean isInline(
85        @NonNull IDefinition definition,
86        @NonNull ModuleIndex metaschemaIndex);
87  }