MIB file "import" really means the objects are from other MIB file (MIB Definition).
| RFC1213-MIB.mib |
IMPORTS
mgmt, NetworkAddress, IpAddress, Counter, Gauge,
TimeTicks
FROM RFC1155-SMI
OBJECT-TYPE
FROM RFC-1212;
|
For example, mgmt is defined in RFC1155-SMI.mib file or OBJECT-TYPE is defined in RFC-1212.mib file.
| RFC1155-SMI.mib |
mgmt OBJECT IDENTIFIER ::= { internet 2 }
|
| RFC-1212.mib |
OBJECT-TYPE MACRO ::=
BEGIN
TYPE NOTATION ::=
-- must conform to
-- RFC1155's ObjectSyntax
"SYNTAX" type(ObjectSyntax)
"ACCESS" Access
"STATUS" Status
DescrPart
ReferPart
IndexPart
DefValPart
VALUE NOTATION ::= value (VALUE ObjectName) <etc etc>
|
Therefore, we need to make the references link across the file.
Xtext provides this via special attributes
"importedNamespace" or "importURI". Since each MIB is enclosed by Definition block and provides Import section - its more closely resemble namespace so "importedNamespace" will be my choice.
Before working directly on MIB grammar, I decided to get familiarize on Xtext import namespace concept using
15 Minutes Tutorial example.
Notice that root rule is using multiplicity - making it single instance causes "Open-Declaration" (i.e F3) feature to stop working - I take this as hint that each files data get appended into a single model container .
| Domainmodel.xtext |
Domainmodel:
// (elements += AbstractElement)*
elements = AbstractElement
;
|
Therefore, the Mib grammar should be modified as follow.
| Mib.xtext |
MibModel:
definitions+=Definition* ;
Definition:
name=ID 'DEFINITIONS' '::=' 'BEGIN'
Export?
imports=Import?
(identifiers+=Identifier | DataType)+
'END';
|
Additionally using that 15 Minutes Tutorial again, lets modify the import syntax something similar to Mib.
| blog.dmodel |
// import my.company.common.HasAuthor
import HasAuthor from my.company.common
|
Therefore the grammar need to be changed as follow:
| Domainmodel.xtext |
Import:
// 'import' importedNamespace = QualifiedNameWithWildcard
'import' lastSegment=(ID|'*') 'from' qname=QualifiedName
;
//QualifiedNameWithWildcard:
// QualifiedName '.*'?
//;
|
Since "importedNamespace" attribute can't be used directly, we lose the default Xtext behaviour and need manual construct of Imported Namespace. This can be done by overriding getImportedNamespace() method from ImportedNamespaceAwareLocalScopeProvider.
| DomainmodelImportedNamespaceAwareLocalScopeProvider.xtend |
package org.example.domainmodel.scoping
import org.eclipse.xtext.scoping.impl.ImportedNamespaceAwareLocalScopeProvider
import org.eclipse.emf.ecore.EObject
import org.example.domainmodel.domainmodel.Import
class DomainmodelImportedNamespaceAwareLocalScopeProvider extends ImportedNamespaceAwareLocalScopeProvider {
override String getImportedNamespace(EObject object) {
if (object instanceof Import)
(object as Import).qname + "." + (object as Import).lastSegment
}
}
|
And to bind this class, override configureIScopeProviderDelegate() as follow:
| DomainmodelRuntimeModule.java |
@Override
public void configureIScopeProviderDelegate(com.google.inject.Binder binder) {
binder.bind(org.eclipse.xtext.scoping.IScopeProvider.class)
.annotatedWith(
com.google.inject.name.Names
.named(org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.NAMED_DELEGATE))
.to(DomainmodelImportedNamespaceAwareLocalScopeProvider.class);
}
|
Now the new import syntax should work.
TODO: Why there is another alternative ImportedNamespaceAwareLocalScopeProvider binding through Model workflow file while we can override this through above method? When or any reason at all to use this?
| GenerateDomainmodel.mwe2 |
fragment = scoping.ImportNamespacesScopingFragment auto-inject {}
|