2525import java .util .List ;
2626import java .util .Map ;
2727import java .util .Set ;
28+ import java .util .Stack ;
2829
2930import javax .annotation .processing .AbstractProcessor ;
3031import javax .annotation .processing .ProcessingEnvironment ;
@@ -180,10 +181,10 @@ private void processElement(Element element) {
180181 if (annotation != null ) {
181182 String prefix = getPrefix (annotation );
182183 if (element instanceof TypeElement ) {
183- processAnnotatedTypeElement (prefix , (TypeElement ) element );
184+ processAnnotatedTypeElement (prefix , (TypeElement ) element , new Stack < TypeElement >() );
184185 }
185186 else if (element instanceof ExecutableElement ) {
186- processExecutableElement (prefix , (ExecutableElement ) element );
187+ processExecutableElement (prefix , (ExecutableElement ) element , new Stack < TypeElement >() );
187188 }
188189 }
189190 }
@@ -192,13 +193,13 @@ else if (element instanceof ExecutableElement) {
192193 }
193194 }
194195
195- private void processAnnotatedTypeElement (String prefix , TypeElement element ) {
196+ private void processAnnotatedTypeElement (String prefix , TypeElement element , Stack < TypeElement > seen ) {
196197 String type = this .metadataEnv .getTypeUtils ().getQualifiedName (element );
197198 this .metadataCollector .add (ItemMetadata .newGroup (prefix , type , type , null ));
198- processTypeElement (prefix , element , null );
199+ processTypeElement (prefix , element , null , seen );
199200 }
200201
201- private void processExecutableElement (String prefix , ExecutableElement element ) {
202+ private void processExecutableElement (String prefix , ExecutableElement element , Stack < TypeElement > seen ) {
202203 if ((!element .getModifiers ().contains (Modifier .PRIVATE ))
203204 && (TypeKind .VOID != element .getReturnType ().getKind ())) {
204205 Element returns = this .processingEnv .getTypeUtils ().asElement (element .getReturnType ());
@@ -213,22 +214,27 @@ private void processExecutableElement(String prefix, ExecutableElement element)
213214 }
214215 else {
215216 this .metadataCollector .add (group );
216- processTypeElement (prefix , (TypeElement ) returns , element );
217+ processTypeElement (prefix , (TypeElement ) returns , element , seen );
217218 }
218219 }
219220 }
220221 }
221222
222- private void processTypeElement (String prefix , TypeElement element , ExecutableElement source ) {
223- new PropertyDescriptorResolver (this .metadataEnv ).resolve (element , source ).forEach ((descriptor ) -> {
224- this .metadataCollector .add (descriptor .resolveItemMetadata (prefix , this .metadataEnv ));
225- if (descriptor .isNested (this .metadataEnv )) {
226- TypeElement nestedTypeElement = (TypeElement ) this .metadataEnv .getTypeUtils ()
227- .asElement (descriptor .getType ());
228- String nestedPrefix = ConfigurationMetadata .nestedPrefix (prefix , descriptor .getName ());
229- processTypeElement (nestedPrefix , nestedTypeElement , source );
230- }
231- });
223+ private void processTypeElement (String prefix , TypeElement element , ExecutableElement source ,
224+ Stack <TypeElement > seen ) {
225+ if (!seen .contains (element )) {
226+ seen .push (element );
227+ new PropertyDescriptorResolver (this .metadataEnv ).resolve (element , source ).forEach ((descriptor ) -> {
228+ this .metadataCollector .add (descriptor .resolveItemMetadata (prefix , this .metadataEnv ));
229+ if (descriptor .isNested (this .metadataEnv )) {
230+ TypeElement nestedTypeElement = (TypeElement ) this .metadataEnv .getTypeUtils ()
231+ .asElement (descriptor .getType ());
232+ String nestedPrefix = ConfigurationMetadata .nestedPrefix (prefix , descriptor .getName ());
233+ processTypeElement (nestedPrefix , nestedTypeElement , source , seen );
234+ }
235+ });
236+ seen .pop ();
237+ }
232238 }
233239
234240 private void processEndpoint (Element element , List <Element > annotations ) {
0 commit comments