docs: public final EObject ruleTypeRef() throws RecognitionException {
          EObject current = null;
  
          Token otherlv_0=null;
          Token otherlv_1=null;
          Token otherlv_2=null;
  
  
          	enterRule();
  
          try {
              // InternalXtext.g:936:2: ( ( ( ( (otherlv_0= RULE_ID ) ) otherlv_1= '::' )? ( (otherlv_2= RULE_ID ) ) ) )
              // InternalXtext.g:937:2: ( ( ( (otherlv_0= RULE_ID ) ) otherlv_1= '::' )? ( (otherlv_2= RULE_ID ) ) )
              {
              // InternalXtext.g:937:2: ( ( ( (otherlv_0= RULE_ID ) ) otherlv_1= '::' )? ( (otherlv_2= RULE_ID ) ) )
              // InternalXtext.g:938:3: ( ( (otherlv_0= RULE_ID ) ) otherlv_1= '::' )? ( (otherlv_2= RULE_ID ) )
              {
              // InternalXtext.g:938:3: ( ( (otherlv_0= RULE_ID ) ) otherlv_1= '::' )?
              int alt24=2;
              int LA24_0 = input.LA(1);
  
              if ( (LA24_0==RULE_ID) ) {
                  int LA24_1 = input.LA(2);
  
                  if ( (LA24_1==29) ) {
                      alt24=1;
                  }
              }
              switch (alt24) {
                  case 1 :
                      // InternalXtext.g:939:4: ( (otherlv_0= RULE_ID ) ) otherlv_1= '::'
                      {
                      // InternalXtext.g:939:4: ( (otherlv_0= RULE_ID ) )
                      // InternalXtext.g:940:5: (otherlv_0= RULE_ID )
                      {
                      // InternalXtext.g:940:5: (otherlv_0= RULE_ID )
                      // InternalXtext.g:941:6: otherlv_0= RULE_ID
                      {
  
                      						if (current==null) {
                      							current = createModelElement(grammarAccess.getTypeRefRule());
                      						}
                      					
                      otherlv_0=(Token)match(input,RULE_ID,FollowSets000.FOLLOW_24); 
  
                      						newLeafNode(otherlv_0, grammarAccess.getTypeRefAccess().getMetamodelAbstractMetamodelDeclarationCrossReference_0_0_0());
                      					
  
                      }
  
  
                      }
  
                      otherlv_1=(Token)match(input,29,FollowSets000.FOLLOW_13); 
  
                      				newLeafNode(otherlv_1, grammarAccess.getTypeRefAccess().getColonColonKeyword_0_1());
                      			
  
                      }
                      break;
  
              }
  
              // InternalXtext.g:957:3: ( (otherlv_2= RULE_ID ) )
              // InternalXtext.g:958:4: (otherlv_2= RULE_ID )
              {
              // InternalXtext.g:958:4: (otherlv_2= RULE_ID )
              // InternalXtext.g:959:5: otherlv_2= RULE_ID
              {
  
              					if (current==null) {
              						current = createModelElement(grammarAccess.getTypeRefRule());
              					}
              				
              otherlv_2=(Token)match(input,RULE_ID,FollowSets000.FOLLOW_2); 
  
              					newLeafNode(otherlv_2, grammarAccess.getTypeRefAccess().getClassifierEClassifierCrossReference_1_0());
              				
  
              }
  
  
              }
  
  
              }
  
  
              }
  
  
              	leaveRule();
  
          }
  
              catch (RecognitionException re) {
                  recover(input,re);
                  appendSkippedTokens();
              }
          finally {
          }
          return current;
      }