Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » [xtext 2] Problem with QualifiedNames
[xtext 2] Problem with QualifiedNames [message #666574] Thu, 21 April 2011 06:13 Go to next message
Alex Ruiz is currently offline Alex RuizFriend
Messages: 103
Registered: March 2011
Senior Member
Greetings,

I have spent a considerable amount of time trying to figure out this, without success. I apologize for the long question.

I'm using Xtext 2 to create an editor for Protocol Buffers (there are like 5 out there, and none of them work.) This work will be open sourced, once we have something to offer.

The problem I have is that with Protocol Buffers, qualified names may or may not include the package. For example, given the package "hello.world" the element "Person" can be referred as "hello.world.Person" or just "Person". So far, in my editor only "hello.world.Person" can be found by Xtext.

How can I enable "multiple" valid QualifiedNames for a element?

I'm attaching a bunch of stuff. Here is the grammar:

grammar com.google.eclipse.protobuf.Protobuf with org.eclipse.xtext.common.Terminals

import "http://www.eclipse.org/emf/2002/Ecore" as ecore
generate protobuf "http://www.google.com/eclipse/protobuf/Protobuf"

Protobuf:
  (syntax=Syntax)?	
  (package=Package)?
  (imports+=Import)*
  (options+=Option)*
  (elements+=ProtobufElement)*;

Syntax:
  'syntax' '=' name=STRING ';';  
  
Package:
  'package' name=QualifiedName ';';

Import: 
  'import' importURI=STRING ';';

QualifiedName:
  ID ('.' ID)*;

Option:
  'option' name=ID '=' value=ValueRef ';';

ProtobufElement:
  Type | ExtendMessage | Service;

Type:
  Message | Enum;

Message:
  'message' name=ID '{'
  elements+=MessageElement*
  ('extensions' extensionsFrom=INT 'to' (extensionsTo=INT | 'max') ';')?
  '}'(';')?;

MessageElement:
  Type | Property;

Property:
  modifier=Modifier type=AbstractTypeReference name=ID '=' index=INT (('[' 'default' '=' default=ValueRef
  ']') | ('[' 'packed' '=' packed=BooleanRef ']'))? ';';

enum Modifier:
  required
  | optional
  | repeated;

AbstractTypeReference:
  ScalarTypeReference | TypeReference;

ScalarTypeReference:
  scalar=ScalarType;

enum ScalarType:
  double
  | float
  | int32
  | int64
  | uint32
  | uint64
  | sint32
  | sint64
  | fixed32
  | fixed64
  | sfixed32
  | sfixed64
  | bool
  | string
  | bytes;

TypeReference:
  type=[Type | QualifiedName];

ValueRef:
  LiteralRef
  | BooleanRef
  | IntRef
  | FloatRef
  | StringRef;

LiteralRef:
  literal=[Literal];

BooleanRef:
  boolean=BOOL;

enum BOOL:
  true
  | false;

IntRef:
  int=INT;

FloatRef:
  float=FLOAT;

StringRef:
  string=STRING;

Enum:
  'enum' name=ID '{'
  literals+=Literal*
  '}' ';'?;

Literal:
  name=ID '=' index=INT ';';

ExtendMessage:
  'extend' message=[Message] '{'
  elements+=MessageElement*
  '}';

Service:
 'service' name=ID '{'
   rpc=Rpc
 '}';

Rpc: 
  'rpc' name=ID  '(' argType=MessageReference ')' 'returns' '(' returnType=MessageReference ')' ';'
;

MessageReference:
  type=[Message | QualifiedName];

terminal INT returns ecore::EInt: ('0'..'9')+;  
terminal FLOAT returns ecore::EFloat: ('0'..'9')* ('.' ('0'..'9')+)?;


In the mwe2 file I have the following:

			// java-based API for validation 
			fragment = validation.JavaValidatorFragment {
				composedCheck = "org.eclipse.xtext.validation.ImportUriValidator"
				composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator"
				// registerForImportedPackages = true
			}

			// scoping and exporting API
			// fragment = scoping.ImportURIScopingFragment {}
			// fragment = exporting.SimpleNamesFragment {}

			// scoping and exporting API 
			fragment = scoping.ImportNamespacesScopingFragment {}
			fragment = exporting.QualifiedNamesFragment {}
			fragment = builder.BuilderIntegrationFragment {}


Since the package is optional, but it should be part of the FQN, I created my own IQualifiedNameProvider. It works fine.

Any help will be greatly appreciated Smile

-Alex
Re: [xtext 2] Problem with QualifiedNames [message #666596 is a reply to message #666574] Thu, 21 April 2011 09:01 Go to previous messageGo to next message
Jan Koehnlein is currently offline Jan KoehnleinFriend
Messages: 760
Registered: July 2009
Location: Hamburg
Senior Member
I don't know about the Protocol Buffers language: What does it mean if
no package is specified?

You should implement an IScopeProvider to put the elements with the
simple names on the scope. This is a good solution if these short names
are only valid a specific referring context, e.g. from elements within
the same package.

Am 21.04.11 08:14, schrieb Alex Ruiz:
> Greetings,
>
> I have spent a considerable amount of time trying to figure out this,
> without success. I apologize for the long question.
>
> I'm using Xtext 2 to create an editor for Protocol Buffers (there are
> like 5 out there, and none of them work.) This work will be open
> sourced, once we have something to offer.
>
> The problem I have is that with Protocol Buffers, qualified names may or
> may not include the package. For example, given the package
> "hello.world" the element "Person" can be referred as
> "hello.world.Person" or just "Person". So far, in my editor only
> "hello.world.Person" can be found by Xtext.
>
> How can I enable "multiple" valid QualifiedNames for a element?
>
> I'm attaching a bunch of stuff. Here is the grammar:
>
>
> grammar com.google.eclipse.protobuf.Protobuf with
> org.eclipse.xtext.common.Terminals
>
> import "http://www.eclipse.org/emf/2002/Ecore" as ecore
> generate protobuf "http://www.google.com/eclipse/protobuf/Protobuf"
>
> Protobuf:
> (syntax=Syntax)?
> (package=Package)?
> (imports+=Import)*
> (options+=Option)*
> (elements+=ProtobufElement)*;
>
> Syntax:
> 'syntax' '=' name=STRING ';';
> Package:
> 'package' name=QualifiedName ';';
>
> Import: 'import' importURI=STRING ';';
>
> QualifiedName:
> ID ('.' ID)*;
>
> Option:
> 'option' name=ID '=' value=ValueRef ';';
>
> ProtobufElement:
> Type | ExtendMessage | Service;
>
> Type:
> Message | Enum;
>
> Message:
> 'message' name=ID '{'
> elements+=MessageElement*
> ('extensions' extensionsFrom=INT 'to' (extensionsTo=INT | 'max') ';')?
> '}'(';')?;
>
> MessageElement:
> Type | Property;
>
> Property:
> modifier=Modifier type=AbstractTypeReference name=ID '=' index=INT (('['
> 'default' '=' default=ValueRef
> ']') | ('[' 'packed' '=' packed=BooleanRef ']'))? ';';
>
> enum Modifier:
> required
> | optional
> | repeated;
>
> AbstractTypeReference:
> ScalarTypeReference | TypeReference;
>
> ScalarTypeReference:
> scalar=ScalarType;
>
> enum ScalarType:
> double
> | float
> | int32
> | int64
> | uint32
> | uint64
> | sint32
> | sint64
> | fixed32
> | fixed64
> | sfixed32
> | sfixed64
> | bool
> | string
> | bytes;
>
> TypeReference:
> type=[Type | QualifiedName];
>
> ValueRef:
> LiteralRef
> | BooleanRef
> | IntRef
> | FloatRef
> | StringRef;
>
> LiteralRef:
> literal=[Literal];
>
> BooleanRef:
> boolean=BOOL;
>
> enum BOOL:
> true
> | false;
>
> IntRef:
> int=INT;
>
> FloatRef:
> float=FLOAT;
>
> StringRef:
> string=STRING;
>
> Enum:
> 'enum' name=ID '{'
> literals+=Literal*
> '}' ';'?;
>
> Literal:
> name=ID '=' index=INT ';';
>
> ExtendMessage:
> 'extend' message=[Message] '{'
> elements+=MessageElement*
> '}';
>
> Service:
> 'service' name=ID '{'
> rpc=Rpc
> '}';
>
> Rpc: 'rpc' name=ID '(' argType=MessageReference ')' 'returns' '('
> returnType=MessageReference ')' ';'
> ;
>
> MessageReference:
> type=[Message | QualifiedName];
>
> terminal INT returns ecore::EInt: ('0'..'9')+; terminal FLOAT returns
> ecore::EFloat: ('0'..'9')* ('.' ('0'..'9')+)?;
>
>
> In the mwe2 file I have the following:
>
>
> // java-based API for validation fragment =
> validation.JavaValidatorFragment {
> composedCheck = "org.eclipse.xtext.validation.ImportUriValidator"
> composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator"
> // registerForImportedPackages = true
> }
>
> // scoping and exporting API
> // fragment = scoping.ImportURIScopingFragment {}
> // fragment = exporting.SimpleNamesFragment {}
>
> // scoping and exporting API fragment =
> scoping.ImportNamespacesScopingFragment {}
> fragment = exporting.QualifiedNamesFragment {}
> fragment = builder.BuilderIntegrationFragment {}
>
>
> Since the package is optional, but it should be part of the FQN, I
> created my own IQualifiedNameProvider. It works fine.
>
> Any help will be greatly appreciated :)
>
> -Alex


--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com


---
Get professional support from the Xtext committers at www.typefox.io
Re: [xtext 2] Problem with QualifiedNames [message #666706 is a reply to message #666596] Thu, 21 April 2011 18:23 Go to previous messageGo to next message
Alex Ruiz is currently offline Alex RuizFriend
Messages: 103
Registered: March 2011
Senior Member
Thanks Jan, I'll follow your advice Smile

In proto language, AFAIK, no package is like a "default" package in Java. That's the reason I didn't specify 'packages' in the element hierarchy in the grammar (mainly because I don't know if it is possible to have "default" values in the grammar.)

Cheers,
-Alex
Re: [xtext 2] Problem with QualifiedNames [message #666739 is a reply to message #666574] Fri, 22 April 2011 06:03 Go to previous message
Alexander Nittka is currently offline Alexander NittkaFriend
Messages: 1193
Registered: July 2009
Senior Member
Hi,

one "problem" is that your package definition does not fit the default namespace semantics assumed by Xtext which is based on containment. That is a child with name "A" of a container with name "B" has the qualified name B.A. Within the container B, A is known as A. Outside it is known as B.A.

For you, the package is just another attribute of A. And hence the default mechanisms do not work.

What you could do: Do not adapt the QualifiedNameProvider and create the scopes yourself, as Jan suggests. In this case you could add an element twice - once using the simple and once using the qualified name (there are utility functions, where you can supply a name calculator for the EObjectDescription-creation).

Another possibility is adapting the QulifiedNameProvider, but adapt the imported namespace calculation to actually add all known namespaces by default. That is, you will have no explicit importing of namespaces but the system behaves as if every name space X.* is imported at every position. That way each element can be referenced by its simple as well as its qualified name.

Note that in case of name clashes (two elements with the same name) none of the two will be visible via its simple name (and if the package coincides it will not be referrable at all).

Alex
Previous Topic:[Xtext] Working with array with Xtext pre-defined Java types
Next Topic:INCLUDE <file>
Goto Forum:
  


Current Time: Wed Apr 24 17:53:59 GMT 2024

Powered by FUDForum. Page generated in 0.03670 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top