text: const experimental_utils_1 = require("@typescript-eslint/experimental-utils");
  const load_1 = require("../utils/load");
  const utils_1 = require("../utils/utils");
  module.exports = {
      name: "call-sync-after-load",
      meta: {
          type: "suggestion",
          messages: {
              callSyncAfterLoad: "Call context.sync() after calling load on '{{name}}' for property '{{loadValue}}' and before reading the property.",
          },
          docs: {
              description: "Always call context.sync() between loading one or more properties on objects and reading any of those properties.",
              category: "Best Practices",
              recommended: false,
              url: "https://docs.microsoft.com/office/dev/add-ins/develop/application-specific-api-model#load",
          },
          schema: [],
      },
      create: function (context) {
          class VariablePropertySet extends Set {
              add(variableProperty) {
                  return super.add(JSON.stringify(variableProperty));
              }
              has(variableProperty) {
                  return super.has(JSON.stringify(variableProperty));
              }
          }
          let apiReferences = [];
          function findLoadBeforeSync() {
              const needSync = new VariablePropertySet();
              apiReferences.forEach((apiReference) => {
                  var _a;
                  const operation = apiReference.operation;
                  const reference = apiReference.reference;
                  const identifier = reference.identifier;
                  const variable = reference.resolved;
                  if (operation === "Load" &&
                      variable &&
                      ((_a = identifier.parent) === null || _a === void 0 ? void 0 : _a.type) == experimental_utils_1.TSESTree.AST_NODE_TYPES.MemberExpression) {
                      const propertyName = load_1.getLoadArgument(identifier.parent);
                      needSync.add({ variable: variable.name, property: propertyName });
                  }
                  if (operation === "Sync") {
                      needSync.clear();
                  }
                  if (operation === "Read" && variable) {
                      const propertyName = utils_1.findPropertiesRead(reference.identifier.parent);
                      if (needSync.has({ variable: variable.name, property: propertyName })) {
                          const node = reference.identifier;
                          context.report({
                              node: node,
                              messageId: "callSyncAfterLoad",
                              data: { name: node.name, loadValue: propertyName },
                          });
                      }
                  }
              });
          }
          return {
              Program() {
                  apiReferences = utils_1.findOfficeApiReferences(context.getScope());
                  apiReferences.sort((left, right) => {
                      return (left.reference.identifier.range[1] -
                          right.reference.identifier.range[1]);
                  });
                  findLoadBeforeSync();
              },
          };
      },
  };
  //# sourceMappingURL=call-sync-after-load.js.map