private EnumBuilder resolveInnerEnumFromTypeDefinition(final EnumTypeDefinition enumTypeDef, final QName enumName,
final GeneratedTypeBuilder typeBuilder, final ModuleContext context) {
if (enumTypeDef != null && typeBuilder != null && enumTypeDef.getQName().getLocalName() != null) {
- final String enumerationName = BindingMapping.getClassName(enumName);
- final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName);
+ final EnumBuilder enumBuilder = typeBuilder.addEnumeration(BindingMapping.getClassName(enumName));
typeProvider.addEnumDescription(enumBuilder, enumTypeDef);
enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef);
context.addInnerTypedefType(enumTypeDef.getPath(), enumBuilder);
"Local Name in EnumTypeDefinition QName cannot be NULL!");
Preconditions.checkArgument(typeBuilder != null, "Generated Type Builder reference cannot be NULL!");
- final String enumerationName = BindingMapping.getClassName(enumName);
-
- final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName);
+ final EnumBuilder enumBuilder = typeBuilder.addEnumeration(BindingMapping.getClassName(enumName));
addEnumDescription(enumBuilder, enumTypeDef);
enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef);
}
@Override
- public EnumBuilder addEnumeration(final String name) {
+ public EnumBuilder addEnumeration(String name) {
Preconditions.checkArgument(name != null, "Name of enumeration cannot be null!");
- final EnumBuilder builder = newEnumerationBuilder(getIdentifier().createEnclosed(name));
+ // This enumeration may be generated from a leaf, which may end up colliding with its enclosing type
+ // hierarchy. Check it and assign another name if that should be the case.
+ final boolean canCreate = getIdentifier().canCreateEnclosed(name);
+ if (!canCreate) {
+ // Append a single '$' -- it cannot come from the user, hence it marks our namespace.
+ name = name + '$';
+ }
+
+ final EnumBuilder builder = newEnumerationBuilder(getIdentifier().createEnclosed(name));
Preconditions.checkArgument(!this.enumDefinitions.contains(builder),
- "This generated type already contains equal enumeration.");
+ "Generated type %s already contains an enumeration for %s", this, builder);
this.enumDefinitions = LazyCollections.lazyAdd(this.enumDefinitions, builder);
return builder;
}
CompilationTestUtils.cleanUp(sourcesOutputDir, compiledOutputDir);
}
+ @Test
+ public void innerEnumerationNameCollisionTest() throws Exception {
+ final File sourcesOutputDir = CompilationTestUtils.generatorOutput("mdsal321");
+ final File compiledOutputDir = CompilationTestUtils.compilerOutput("mdsal321");
+ generateTestSources("/compilation/mdsal321", sourcesOutputDir);
+ CompilationTestUtils.testCompilation(sourcesOutputDir, compiledOutputDir);
+ CompilationTestUtils.cleanUp(sourcesOutputDir, compiledOutputDir);
+ }
+
private void generateTestSources(final String resourceDirPath, final File sourcesOutputDir)
throws IOException, URISyntaxException {
final List<File> sourceFiles = CompilationTestUtils.getSourceFiles(resourceDirPath);
--- /dev/null
+module odl-mdsal {
+ namespace "urn:odl:mdsal321";
+ prefix odl;
+
+ container foo {
+ leaf foo {
+ type enumeration {
+ enum "foo";
+ }
+ description "Enumeration defined in a leaf. This triggers a nested
+ class with a name derived from leaf name to be created
+ in a class from container name. Both names are 'foo'.
+ Measures have to be taken to rename the class, so it
+ does not clash with its enclosing class.";
+ }
+ }
+}