1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package dev.metaschema.databind.codegen.typeinfo;
7   
8   import com.squareup.javapoet.ClassName;
9   
10  import java.util.List;
11  
12  import dev.metaschema.core.model.IAssemblyDefinition;
13  import dev.metaschema.core.model.IAssemblyInstanceAbsolute;
14  import dev.metaschema.core.model.IChoiceGroupInstance;
15  import dev.metaschema.core.model.IFieldDefinition;
16  import dev.metaschema.core.model.IFieldInstance;
17  import dev.metaschema.core.model.IFieldInstanceAbsolute;
18  import dev.metaschema.core.model.IModelDefinition;
19  import dev.metaschema.core.model.IModule;
20  import dev.metaschema.core.model.INamedModelInstanceAbsolute;
21  import dev.metaschema.core.model.INamedModelInstanceGrouped;
22  import dev.metaschema.databind.codegen.config.IBindingConfiguration;
23  import dev.metaschema.databind.codegen.typeinfo.def.IAssemblyDefinitionTypeInfo;
24  import dev.metaschema.databind.codegen.typeinfo.def.IDefinitionTypeInfo;
25  import dev.metaschema.databind.codegen.typeinfo.def.IFieldDefinitionTypeInfo;
26  import dev.metaschema.databind.codegen.typeinfo.def.IModelDefinitionTypeInfo;
27  import edu.umd.cs.findbugs.annotations.NonNull;
28  import edu.umd.cs.findbugs.annotations.Nullable;
29  
30  /**
31   * Resolves type information for Metaschema constructs.
32   * <p>
33   * This interface provides methods for resolving Java class names, package
34   * names, and type information for Metaschema modules, definitions, and
35   * instances.
36   */
37  public interface ITypeResolver {
38    /**
39     * Construct a new type resolver using the default implementation.
40     *
41     * @param bindingConfiguration
42     *          the binding configuration used to configure types
43     * @return the type resolver
44     */
45    @NonNull
46    static ITypeResolver newTypeResolver(@NonNull IBindingConfiguration bindingConfiguration) {
47      return new DefaultTypeResolver(bindingConfiguration);
48    }
49  
50    /**
51     * Get the binding configuration used by this type resolver.
52     *
53     * @return the binding configuration
54     */
55    @NonNull
56    IBindingConfiguration getBindingConfiguration();
57  
58    /**
59     * Get type information for the provided {@code instance}.
60     *
61     * @param instance
62     *          the instance to get type information for
63     * @param parent
64     *          the type information for the parent definition containing this
65     *          instance
66     * @return the type information
67     */
68    @NonNull
69    default INamedModelInstanceTypeInfo getTypeInfo(
70        @NonNull INamedModelInstanceAbsolute instance,
71        @NonNull IAssemblyDefinitionTypeInfo parent) {
72      INamedModelInstanceTypeInfo retval;
73      if (instance instanceof IAssemblyInstanceAbsolute) {
74        retval = new AssemblyInstanceTypeInfoImpl((IAssemblyInstanceAbsolute) instance, parent);
75      } else if (instance instanceof IFieldInstance) {
76        retval = new FieldInstanceTypeInfoImpl((IFieldInstanceAbsolute) instance, parent);
77      } else {
78        throw new UnsupportedOperationException(instance.getClass().getName());
79      }
80      return retval;
81    }
82  
83    /**
84     * Get type information for the provided {@code instance}.
85     *
86     * @param instance
87     *          the instance to get type information for
88     * @param parent
89     *          the type information for the parent definition containing this
90     *          instance
91     * @return the type information
92     */
93    @NonNull
94    default IChoiceGroupTypeInfo getTypeInfo(
95        @NonNull IChoiceGroupInstance instance,
96        @NonNull IAssemblyDefinitionTypeInfo parent) {
97      return new ChoiceGroupTypeInfoImpl(instance, parent);
98    }
99  
100   /**
101    * Get type information for the provided grouped model {@code instance}.
102    *
103    * @param modelInstance
104    *          the grouped model instance to get type information for
105    * @param choiceGroupTypeInfoImpl
106    *          the type information for the parent choice group containing this
107    *          instance
108    * @return the type information
109    */
110   @NonNull
111   IGroupedNamedModelInstanceTypeInfo getTypeInfo(
112       @NonNull INamedModelInstanceGrouped modelInstance,
113       @NonNull IChoiceGroupTypeInfo choiceGroupTypeInfoImpl);
114 
115   /**
116    * Get type information for the provided {@code definition}.
117    *
118    * @param definition
119    *          the definition to get type information for
120    * @return the type information
121    */
122   @NonNull
123   IAssemblyDefinitionTypeInfo getTypeInfo(@NonNull IAssemblyDefinition definition);
124 
125   /**
126    * Get type information for the provided {@code definition}.
127    *
128    * @param definition
129    *          the definition to get type information for
130    * @return the type information
131    */
132   @NonNull
133   IFieldDefinitionTypeInfo getTypeInfo(@NonNull IFieldDefinition definition);
134 
135   /**
136    * Get type information for the provided {@code definition}.
137    *
138    * @param definition
139    *          the definition to get type information for
140    * @return the type information
141    */
142   @NonNull
143   IModelDefinitionTypeInfo getTypeInfo(@NonNull IModelDefinition definition);
144 
145   /**
146    * Get the name of the class associated with the provided Metaschema instance.
147    *
148    * @param instance
149    *          the Metaschema instance to get the class name for
150    * @return the class name information for the Module module
151    */
152   @NonNull
153   ClassName getClassName(IChoiceGroupInstance instance);
154 
155   /**
156    * Get the name of the class associated with the provided Metaschema module.
157    *
158    * @param module
159    *          the Metaschema module to get the class name for
160    * @return the class name information for the Module module
161    */
162   @NonNull
163   ClassName getClassName(@NonNull IModule module);
164 
165   /**
166    * Get the name of the class associated with the provided Metaschema definition.
167    *
168    * @param definition
169    *          the Metaschema definition to get the class name for
170    * @return the class name information for the definition
171    */
172   @NonNull
173   ClassName getClassName(@NonNull IModelDefinition definition);
174 
175   /**
176    * Get the name of the class associated with the provided Metaschema definition.
177    *
178    * @param typeInfo
179    *          the type information to get the class name for
180    * @return the class name information for the definition
181    */
182   @NonNull
183   ClassName getClassName(@NonNull INamedModelInstanceTypeInfo typeInfo);
184 
185   /**
186    * Get the name of the super interfaces associated with the provided Metaschema
187    * definition.
188    *
189    * @param definition
190    *          the Metaschema definition to get the super ineterfaces for
191    * @return the super interface information for the definition
192    */
193   @NonNull
194   List<ClassName> getSuperinterfaces(@NonNull IModelDefinition definition);
195 
196   /**
197    * Get the name of the class associated with the provided Metaschema definition
198    * using the provided {@code postfix}. This class will be a child of the
199    * provided parent class.
200    *
201    * @param parentClass
202    *          the containing class
203    * @param suggestedClassName
204    *          the name to derive the subclass name from
205    * @param definition
206    *          the Metaschema definition to get the class name for
207    * @return the class name information for the definition
208    */
209   @NonNull
210   ClassName getSubclassName(
211       @NonNull ClassName parentClass,
212       @NonNull String suggestedClassName,
213       @NonNull IModelDefinition definition);
214 
215   /**
216    * Get the name of the base class to use for the class associated with the
217    * provided Metaschema definition.
218    *
219    * @param definition
220    *          a definition that may be built as a class
221    * @return the name of the base class or {@code null} if no base class is to be
222    *         used
223    */
224   @Nullable
225   ClassName getBaseClassName(@NonNull IModelDefinition definition);
226 
227   /**
228    * Get the Java package name to use for the provided Module module.
229    *
230    * @param module
231    *          the Module module
232    * @return the Java package name
233    */
234   @NonNull
235   String getPackageName(@NonNull IModule module);
236 
237   /**
238    * Get a unique property name for use within the given parent definition.
239    *
240    * @param parent
241    *          the type information for the parent definition
242    * @param name
243    *          the base name to derive the property name from
244    * @return a unique property name suitable for use in the generated class
245    */
246   @NonNull
247   String getPropertyName(@NonNull IDefinitionTypeInfo parent, @NonNull String name);
248 }