private UnityApiEventFunction ParseMessage()

in tools/apiParser/src/ApiParser.cs [171:270]


        private UnityApiEventFunction ParseMessage(string className, SimpleHtmlNode message, Version apiVersion,
            string hintNamespace, RiderSupportedLanguages langCode)
        {
            var link = message.SelectOne(@"td.lbl/a");
            var desc = message.SelectOne(@"td.desc");
            if (link == null || desc == null) return null;

            var detailsPath = link[@"href"];
            if (string.IsNullOrWhiteSpace(detailsPath)) return null;

            var path = Path.Combine(ScriptReferenceRelativePath, detailsPath);
            if (!File.Exists(path)) return null;

            var detailsDoc = SimpleHtmlNode.Load(path);
            var details = detailsDoc?.SelectOne(@"//div.content/div.section");
            var signature = details?.SelectOne(@"div.mb20.clear/h1.heading.inherit");
            var staticNode = details?.SelectOne(@"div.subsection/p/code.varname[text()='static']");

            if (signature == null) return null;

            var isCoroutine = IsCoroutineRegex.IsMatch(details.Text);

            var messageName = link.Text;
            var returnType = ApiType.Void;
            var argumentNames = EmptyArray<string>.Instance;
            var isStaticFromExample = false;

            // Unity 2020.2.0a18 includes EditorWindow.hasUnsavedChanges and EditorWindow.saveChangesMessage as messages
            if (className == "EditorWindow" &&
                (messageName == "hasUnsavedChanges" || messageName == "saveChangesMessage"))
            {
                Console.WriteLine($"Skipping {className}.{messageName} - not a message");
                return null;
            }

            var examples = PickExample(details);
            if (examples.Length > 0)
            {
                var tuple = ParseDetailsFromExample(messageName, examples, hintNamespace);

                // As of 2017.4, the docs for MonoBehaviour.OnCollisionEnter2D don't include a valid example. It demonstrates
                // OnTriggerEnter2D instead. Similar problems for these other methods
                if (tuple == null)
                {
                    var fullName = $"{className}.{messageName}";
                    switch (fullName)
                    {
                        case "MonoBehaviour.OnCollisionEnter2D":
                        case "MonoBehaviour.OnCollisionExit2D":
                        case "MonoBehaviour.OnCollisionStay2D":
                        case "MonoBehaviour.Start":
                        case "MonoBehaviour.OnDestroy":
                        case "EditorWindow.OnProjectChange":
                        case "AssetPostprocessor.OnPostprocessSprites"
                            : // 2018.3 adds example with incorrect casing - OnPostProcessSprites
                            Console.WriteLine(
                                $"WARNING: Unable to parse example for {fullName}. Example incorrect in docs");
                            break;

//                        case "Network.OnDisconnectedFromServer":
//                            Bug in 2018.2 documentation
//                            Console.WriteLine($"WARNING: Missing example for {fullName}");
//                            break;

                        default:
                            foreach (var example in examples)
                            {
                                Console.WriteLine(example.Text);
                                Console.WriteLine();
                            }

                            throw new InvalidOperationException(
                                $"Failed to parse example for {className}.{messageName}");
                    }
                }

                if (tuple != null)
                {
                    returnType = tuple.Item1;
                    argumentNames = tuple.Item2;
                    isStaticFromExample = tuple.Item3;
                }
            }

            if (Equals(returnType, ApiType.IEnumerator))
            {
                returnType = ApiType.Void;
                isCoroutine = true;
            }

            var docPath = Path.Combine(ScriptReferenceRelativePath, detailsPath);
            var eventFunction = new UnityApiEventFunction(messageName, staticNode != null || isStaticFromExample,
                isCoroutine, returnType, apiVersion, docPath);

            eventFunction.AddDescription(desc.Text, langCode);
            
            return ParseParameters(eventFunction, signature, details, hintNamespace, argumentNames, apiVersion, langCode)
                ? eventFunction
                : null;
        }