Getting Started with Poly Symbols

Hello, I’m trying to make a plugin which will help with creating, editing and maintaining YAML that’s used to define content in a video game. All of the YAML is of the same basic form which is a document with its top level value being a sequence of YAML mappings/objects with at least id and typefields. (Example here)

The YAML mappings are referred to as “prototypes”, and they can relate to each other in ways that’re more complex than mere YAML – they are themselves declarations of a prototype, they can contain references to other prototypes, and they can be abstract and/or inherit from other prototypes.

All of these semantics on top of what’s otherwise standard YAML conforming to a schema is why I think the Poly Symbol framework is exactly the sort of tool I want to use to make my plugin.


What I’m struggling with, though, is the poor documentation of this admittedly new and experimental framework. The little documentation that is there says that all one needs do is implement some interfaces and functionality just starts working out of the box. I’ve struggled and failed to get that to work, so I am asking for some guidance (which maybe somebody else can find when they get stuck, too!).

Anyway, what I’ve got so far is here – I pared it down to the absolute basics to try to get usage/declaration search working before trying to do anything else. To achieve this, I have defined two symbol types:

  • Prototype
  • PrototypeReference

In this example YAML document

- type: someProto
  id: myPrototype

- type: someReferencingProto
  id: myReferringProto
  refersTo: myPrototype

, I would expect three symbols, one Prototype for each YAML mapping, and one PrototypeReference for the myProto in the second YAML mapping’s refersTo: myPrototype.

Because the first prototype has a qualified name of robust-yaml/prototype/myPrototype and the reference is a

PolySymbolWithPattern by ReferencingPolySymbol.create(Prototype.qualifiedKind, source.textValue, polySymbolOrigin)

, this is where I would expect the out-of-the-box behavior to just work; the reference is a Poly Symbol which specifically says “I refer to something named robust-yaml/prototype/myPrototype”. Maybe that’s not how it works, but that’s why I’m here.


I originally got some behavior working, but that was by making Prototype References be provided by a PsiPolySymbolReferenceProvider<YAMLScalar>. It worked, but since the usages were the actual YAML Psi Elements, I wasn’t able to configure their presentation. Ultimately this lead me to believe it was functionally incorrect to say the YAMLScalar is the reference, it should be a Poly Symbol derived from that YAMLScalar which is the reference.


Let me know if there is any more information I can provide to clarify what I have, what I’m trying to do, or anything like that.
Initially, I had tried implementing this support by cloning the YAML parser and making a whole new language, so believe me when I say I am very excited by the idea of the Poly Symbol framework and what it seems like it will be able to do.

Thank you in advance for whatever help you may be able to provide :person_bowing:

Chances are you do not need even poly symbols. Most likely simple PsiReference and/or Symbol would do.

I suppose I’d not realized it was possible to have just arbitrary symbols. Looking at the doc, I see Symbols | IntelliJ Platform Plugin SDK , so I’ll check that out.

Just for completeness, what is the case for Poly Symbols if not something like my case?
I gather than the initial reasoning was that it was a way to layer JS frameworks on top of JS/HTML, so is your thinking just that that level of capability is more than I would need here?

Poly Symbol API simplifies life for references that can be contributed externally by plugins for things such as String literals or data languages (JSON/XML/YAML) where the language does not control the semantics of constructs. It provides a generic layer, which allows sharing of Symbols between different languages and technologies. The biggest use is Web Types | IntelliJ Platform Plugin SDK where symbols are configured, not coded.

In case of just YAML and some schema you can contribute simpler PsiReference things on top of JSON schema for it.

Okay, I think I understand your meaning.
In my case, the most basic “semantics of constructs” wouldn’t change, but the “sharing of symbols between different languages and technologies” part still sticks out to me.

In my case, this YAML deserializes into C# objects, and the effective schema (there’s no explicit schema) is defined by the serialization model defined in C#, which can change independently of my plugin’s lifecycle.

I didn’t mention it in the OP because I didn’t think it was immediately relevant, but would it be possible to implement “sharing of symbols between [YAML and C#]” with just symbols, or is that somehow uniquely enabled with Poly Symbols?


To concretize what I mean, from my YAML examples above:

- type: entity
  parent: BaseMentalAction # allow reading laws when crit
  id: ActionViewLaws
  name: View Laws
  description: View the laws that you must follow.
  components:
  - type: Action
    itemIconStyle: NoItem
    icon:
      sprite: Interface/Actions/actions_borg.rsi
      state: state-laws
    useDelay: 0.5
  - type: InstantAction
    event: !type:ToggleLawsScreenEvent

, there is a C# class EntityPrototype which informs that type: entity is valid, and what other fields need to appear in a YAML mapping with type: entity. So I’d want the entity in type: entity to be a reference to that C# class definition, and vice-versa with this YAML mapping being a usage of the class.
(In addition to further enriching interop like C# modifications causing the YAML to report as invalid, etc.)

I am afraid you will not be able to use polysymbols in C# so easily because of how Rider is implemented, it is very different approach