1 /*
2 * SPDX-FileCopyrightText: none
3 * SPDX-License-Identifier: CC0-1.0
4 */
5
6 package dev.metaschema.core.model;
7
8 import java.util.Locale;
9
10 import dev.metaschema.core.model.constraint.IFeatureValueConstrained;
11 import dev.metaschema.core.qname.IEnhancedQName;
12 import edu.umd.cs.findbugs.annotations.NonNull;
13 import edu.umd.cs.findbugs.annotations.Nullable;
14
15 /**
16 * Represents a definition of a flag, field, or assembly in a Metaschema module.
17 * <p>
18 * Definitions are reusable components that specify the structure and
19 * constraints for data elements. They can be referenced by instances or defined
20 * inline.
21 */
22 public interface IDefinition extends INamedModelElement, IAttributable, IFeatureValueConstrained {
23 /**
24 * Describes the visibility of a definition to other modules.
25 */
26 enum ModuleScope {
27 /**
28 * The definition is scoped to only the defining module.
29 */
30 PRIVATE,
31 /**
32 * The definition is scoped to its defining module and any importing module.
33 */
34 PUBLIC;
35 }
36
37 /**
38 * The default module scope for definitions.
39 */
40 @NonNull
41 ModuleScope DEFAULT_MODULE_SCOPE = ModuleScope.PUBLIC;
42
43 /**
44 * Retrieve the definition's scope within the context of its defining module.
45 *
46 * @return the module scope
47 */
48 @NonNull
49 default ModuleScope getModuleScope() {
50 return ModuleScope.PRIVATE;
51 }
52
53 /**
54 * The qualified name for the definition.
55 * <p>
56 * This name is the combination of the definition's namespace, which is the
57 * module's namespace, and the definition's name.
58 *
59 * @return the definition's qualified name
60 */
61 @NonNull
62 IEnhancedQName getDefinitionQName();
63
64 /**
65 * Determine if the definition is defined inline, meaning the definition is
66 * declared where it is used.
67 * <p>
68 * If this method returns {@code false}, then {@link #getInlineInstance()} must
69 * return {@code null}.
70 *
71 * @return {@code true} if the definition is declared inline or {@code false} if
72 * the definition is able to be globally referenced
73 * @see #getInlineInstance()
74 */
75 default boolean isInline() {
76 return getInlineInstance() != null;
77 }
78
79 /**
80 * If {@link #isInline()} is {@code true}, return the instance the definition is
81 * inlined for.
82 * <p>
83 * If this method returns {@code null}, then {@link #getInlineInstance()} must
84 * return {@code false}.
85 *
86 * @return the instance or {@code null} otherwise
87 * @see #isInline()
88 */
89 INamedInstance getInlineInstance();
90
91 /**
92 * Generates a coordinate string for the provided information element
93 * definition.
94 *
95 * A coordinate consists of the element's:
96 * <ul>
97 * <li>containing Metaschema's short name
98 * <li>model type
99 * <li>name
100 * <li>hash code
101 * </ul>
102 *
103 * @return the coordinate
104 */
105 @SuppressWarnings("null")
106 @Override
107 default String toCoordinates() {
108 return String.format("%s:%s-definition:%s(%d)",
109 getContainingModule().getShortName(),
110 getModelType().toString().toUpperCase(Locale.ROOT),
111 getName(),
112 hashCode());
113 }
114
115 /**
116 * Get the resource location information for the provided item, if known.
117 *
118 * @param itemValue
119 * the item to get the location information for
120 *
121 * @return the resource location information, or {@code null} if not known
122 */
123 @Nullable
124 default IResourceLocation getLocation(@NonNull Object itemValue) {
125 return itemValue instanceof IBoundObject ? ((IBoundObject) itemValue).getMetaschemaData() : null;
126 }
127 }