001/* 002 * SPDX-FileCopyrightText: none 003 * SPDX-License-Identifier: CC0-1.0 004 */ 005 006package dev.metaschema.core.model; 007 008import java.util.Locale; 009 010import dev.metaschema.core.model.constraint.IFeatureValueConstrained; 011import dev.metaschema.core.qname.IEnhancedQName; 012import edu.umd.cs.findbugs.annotations.NonNull; 013import edu.umd.cs.findbugs.annotations.Nullable; 014 015/** 016 * Represents a definition of a flag, field, or assembly in a Metaschema module. 017 * <p> 018 * Definitions are reusable components that specify the structure and 019 * constraints for data elements. They can be referenced by instances or defined 020 * inline. 021 */ 022public interface IDefinition extends INamedModelElement, IAttributable, IFeatureValueConstrained { 023 /** 024 * Describes the visibility of a definition to other modules. 025 */ 026 enum ModuleScope { 027 /** 028 * The definition is scoped to only the defining module. 029 */ 030 PRIVATE, 031 /** 032 * The definition is scoped to its defining module and any importing module. 033 */ 034 PUBLIC; 035 } 036 037 /** 038 * The default module scope for definitions. 039 */ 040 @NonNull 041 ModuleScope DEFAULT_MODULE_SCOPE = ModuleScope.PUBLIC; 042 043 /** 044 * Retrieve the definition's scope within the context of its defining module. 045 * 046 * @return the module scope 047 */ 048 @NonNull 049 default ModuleScope getModuleScope() { 050 return ModuleScope.PRIVATE; 051 } 052 053 /** 054 * The qualified name for the definition. 055 * <p> 056 * This name is the combination of the definition's namespace, which is the 057 * module's namespace, and the definition's name. 058 * 059 * @return the definition's qualified name 060 */ 061 @NonNull 062 IEnhancedQName getDefinitionQName(); 063 064 /** 065 * Determine if the definition is defined inline, meaning the definition is 066 * declared where it is used. 067 * <p> 068 * If this method returns {@code false}, then {@link #getInlineInstance()} must 069 * return {@code null}. 070 * 071 * @return {@code true} if the definition is declared inline or {@code false} if 072 * the definition is able to be globally referenced 073 * @see #getInlineInstance() 074 */ 075 default boolean isInline() { 076 return getInlineInstance() != null; 077 } 078 079 /** 080 * If {@link #isInline()} is {@code true}, return the instance the definition is 081 * inlined for. 082 * <p> 083 * If this method returns {@code null}, then {@link #getInlineInstance()} must 084 * return {@code false}. 085 * 086 * @return the instance or {@code null} otherwise 087 * @see #isInline() 088 */ 089 INamedInstance getInlineInstance(); 090 091 /** 092 * Generates a coordinate string for the provided information element 093 * definition. 094 * 095 * A coordinate consists of the element's: 096 * <ul> 097 * <li>containing Metaschema's short name 098 * <li>model type 099 * <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}