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.AnnotationSpec;
9   import com.squareup.javapoet.FieldSpec;
10  import com.squareup.javapoet.MethodSpec;
11  
12  import dev.metaschema.core.datatype.markup.MarkupLine;
13  import dev.metaschema.core.model.INamedModelInstanceAbsolute;
14  import edu.umd.cs.findbugs.annotations.NonNull;
15  import edu.umd.cs.findbugs.annotations.Nullable;
16  
17  public interface INamedModelInstanceTypeInfo extends IModelInstanceTypeInfo {
18    @Override
19    INamedModelInstanceAbsolute getInstance();
20  
21    /**
22     * Set the choice ID for this instance.
23     * <p>
24     * This should be called when the instance is part of a Metaschema choice to
25     * associate it with its choice group.
26     *
27     * @param choiceId
28     *          the choice ID to set, or {@code null} to clear it
29     */
30    void setChoiceId(@Nullable String choiceId);
31  
32    /**
33     * Generate annotation values that are common to all named model instances.
34     *
35     * @param annotation
36     *          the annotation builder.
37     */
38    default void buildBindingAnnotationCommon(@NonNull AnnotationSpec.Builder annotation) {
39      TypeInfoUtils.buildCommonBindingAnnotationValues(getInstance(), annotation);
40    }
41  
42    /**
43     * {@inheritDoc}
44     *
45     * <p>
46     * This implementation adds the effective description from the named model
47     * instance as the field's Javadoc content.
48     */
49    @Override
50    default void buildFieldJavadoc(@NonNull FieldSpec.Builder builder) {
51      MarkupLine description = getInstance().getEffectiveDescription();
52      if (description != null) {
53        builder.addJavadoc("$L\n", description.toHtml());
54      }
55    }
56  
57    /**
58     * {@inheritDoc}
59     *
60     * <p>
61     * This implementation generates getter Javadoc using the instance's formal name
62     * (if available) or property name, adds the effective description, and includes
63     * an appropriate {@code @return} tag based on whether the property is required
64     * or a collection.
65     */
66    @Override
67    default void buildGetterJavadoc(@NonNull MethodSpec.Builder builder) {
68      MarkupLine description = getInstance().getEffectiveDescription();
69      String formalName = getInstance().getEffectiveFormalName();
70      String propertyName = getInstance().getEffectiveName();
71  
72      // Use formal name if available, otherwise property name
73      if (formalName != null) {
74        builder.addJavadoc("Get the \"{@literal $L}\".\n", formalName);
75      } else {
76        builder.addJavadoc("Get the {@code $L} property.\n", propertyName);
77      }
78  
79      // Add description as a second paragraph if available
80      if (description != null) {
81        builder.addJavadoc("\n");
82        builder.addJavadoc("<p>\n");
83        builder.addJavadoc("$L\n", description.toHtml());
84      }
85  
86      builder.addJavadoc("\n");
87      // Collections are always @NonNull (lazy initialized), required singles are
88      // @NonNull
89      if (isRequired() || isCollectionType()) {
90        builder.addJavadoc("@return the $L value\n", propertyName);
91      } else {
92        builder.addJavadoc("@return the $L value, or {@code null} if not set\n", propertyName);
93      }
94    }
95  
96    /**
97     * {@inheritDoc}
98     *
99     * <p>
100    * This implementation generates setter Javadoc using the instance's formal name
101    * (if available) or property name, adds the effective description, and includes
102    * a {@code @param} tag for the value parameter.
103    */
104   @Override
105   default void buildSetterJavadoc(@NonNull MethodSpec.Builder builder, @NonNull String paramName) {
106     MarkupLine description = getInstance().getEffectiveDescription();
107     String formalName = getInstance().getEffectiveFormalName();
108     String propertyName = getInstance().getEffectiveName();
109 
110     // Use formal name if available, otherwise property name
111     if (formalName != null) {
112       builder.addJavadoc("Set the \"{@literal $L}\".\n", formalName);
113     } else {
114       builder.addJavadoc("Set the {@code $L} property.\n", propertyName);
115     }
116 
117     // Add description as a second paragraph if available
118     if (description != null) {
119       builder.addJavadoc("\n");
120       builder.addJavadoc("<p>\n");
121       builder.addJavadoc("$L\n", description.toHtml());
122     }
123 
124     builder.addJavadoc("\n");
125     builder.addJavadoc("@param $L\n", paramName);
126     // Collections and required properties require non-null values;
127     // optional properties can be set to null to clear
128     if (isRequired() || isCollectionType()) {
129       builder.addJavadoc("          the $L value to set\n", propertyName);
130     } else {
131       builder.addJavadoc("          the $L value to set, or {@code null} to clear\n", propertyName);
132     }
133   }
134 }