SyntaxNodeDescriptor (@NotNull Plist plist, @Nullable SyntaxNodeDescriptor parentNode, @NotNull Interner<CharSequence> interner) { PListValue scopeNameValue = plist.getPlistValue(Constants.StringKey.SCOPE_NAME.value); CharSequence scopeName = scopeNameValue != null ? interner.intern(scopeNameValue.getString()) : null; MutableSyntaxNodeDescriptor result = new SyntaxNodeDescriptorImpl(scopeName, parentNode); if (scopeName != null) { rulesMap.put(scopeName, result); } for (Map.Entry<String, PListValue> entry : plist.entries()) { PListValue pListValue = entry.getValue(); if (pListValue != null) { String key = entry.getKey(); Constants.StringKey stringKey = Constants.StringKey.fromName(key); if (stringKey != null) { String stringValue = pListValue.getString(); if (stringValue != null) { result.setStringAttribute(stringKey, interner.intern(stringValue)); } continue; } Constants.CaptureKey captureKey = Constants.CaptureKey.fromName(key); if (captureKey != null) { result.setCaptures(captureKey, loadCaptures(pListValue.getPlist(), interner)); continue; } if (Constants.REPOSITORY_KEY.equalsIgnoreCase(key)) { loadRepository(result, pListValue, interner); } else if (Constants.PATTERNS_KEY.equalsIgnoreCase(key)) { loadPatterns(result, pListValue, interner); } else if (Constants.INJECTIONS_KEY.equalsIgnoreCase(key)) { loadInjections(result, pListValue, interner); } } } result.compact(); return result; }