/*
Scalar type extensions have the potential to be invalid if incorrectly defined.

The named type must already be defined and must be a Scalar type.
Any directives provided must not already apply to the original Scalar type.
11973
private void checkScalarTypeExtensions(List<GraphQLError> errors, TypeDefinitionRegistry typeRegistry) {
        typeRegistry.scalarTypeExtensions()
                .forEach((name, extensions) -> {
                    checkTypeExtensionHasCorrespondingType(errors, typeRegistry, name, extensions, ScalarTypeDefinition.class);
                    checkTypeExtensionDirectiveRedefinition(errors, typeRegistry, name, extensions, ScalarTypeDefinition.class);
                });

    }
1117136
def parse_enum_type_extension(lexer: Lexer) -> Node:
    """"""
    start = lexer.token
    expect_keyword(lexer, "extend")
    expect_keyword(lexer, "enum")
    name = parse_name(lexer)
    directives = parse_directives(lexer, True)
    values = parse_enum_values_definition(lexer)
    if not (directives or values):
        raise unexpected(lexer)
    return Node(
        name=name, directives=directives, values=values, loc=loc(lexer, start)
    )
733948
private function initTypeExtensions()
    {
        $this->typeExtensions = [];

        foreach ($this->loadTypeExtensions() as $extension) {
            if (!$extension instanceof BlockTypeExtensionInterface) {
                throw new UnexpectedTypeException($extension, 'Fxp\Component\Block\BlockTypeExtensionInterface');
            }

            foreach ($extension::getExtendedTypes() as $extendedType) {
                $this->typeExtensions[$extendedType][] = $extension;
            }
        }
    }
44171
public TypeDefinitionRegistry merge(TypeDefinitionRegistry typeRegistry) throws SchemaProblem {
        List<GraphQLError> errors = new ArrayList<>();

        Map<String, TypeDefinition> tempTypes = new LinkedHashMap<>();
        typeRegistry.types.values().forEach(newEntry -> {
            Optional<GraphQLError> defined = define(this.types, tempTypes, newEntry);
            defined.ifPresent(errors::add);
        });

        Map<String, DirectiveDefinition> tempDirectiveDefs = new LinkedHashMap<>();
        typeRegistry.directiveDefinitions.values().forEach(newEntry -> {
            Optional<GraphQLError> defined = define(this.directiveDefinitions, tempDirectiveDefs, newEntry);
            defined.ifPresent(errors::add);
        });

        Map<String, ScalarTypeDefinition> tempScalarTypes = new LinkedHashMap<>();
        typeRegistry.scalarTypes.values().forEach(newEntry -> define(this.scalarTypes, tempScalarTypes, newEntry).ifPresent(errors::add));

        if (typeRegistry.schema != null && this.schema != null) {
            errors.add(new SchemaRedefinitionError(this.schema, typeRegistry.schema));
        }

        if (!errors.isEmpty()) {
            throw new SchemaProblem(errors);
        }

        if (this.schema == null) {
            // ensure schema is not overwritten by merge
            this.schema = typeRegistry.schema;
        }

        // ok commit to the merge
        this.types.putAll(tempTypes);
        this.scalarTypes.putAll(tempScalarTypes);
        this.directiveDefinitions.putAll(tempDirectiveDefs);
        //
        // merge type extensions since they can be redefined by design
        typeRegistry.objectTypeExtensions.forEach((key, value) -> {
            List<ObjectTypeExtensionDefinition> currentList = this.objectTypeExtensions
                    .computeIfAbsent(key, k -> new ArrayList<>());
            currentList.addAll(value);
        });
        typeRegistry.interfaceTypeExtensions.forEach((key, value) -> {
            List<InterfaceTypeExtensionDefinition> currentList = this.interfaceTypeExtensions
                    .computeIfAbsent(key, k -> new ArrayList<>());
            currentList.addAll(value);
        });
        typeRegistry.unionTypeExtensions.forEach((key, value) -> {
            List<UnionTypeExtensionDefinition> currentList = this.unionTypeExtensions
                    .computeIfAbsent(key, k -> new ArrayList<>());
            currentList.addAll(value);
        });
        typeRegistry.enumTypeExtensions.forEach((key, value) -> {
            List<EnumTypeExtensionDefinition> currentList = this.enumTypeExtensions
                    .computeIfAbsent(key, k -> new ArrayList<>());
            currentList.addAll(value);
        });
        typeRegistry.scalarTypeExtensions.forEach((key, value) -> {
            List<ScalarTypeExtensionDefinition> currentList = this.scalarTypeExtensions
                    .computeIfAbsent(key, k -> new ArrayList<>());
            currentList.addAll(value);
        });
        typeRegistry.inputObjectTypeExtensions.forEach((key, value) -> {
            List<InputObjectTypeExtensionDefinition> currentList = this.inputObjectTypeExtensions
                    .computeIfAbsent(key, k -> new ArrayList<>());
            currentList.addAll(value);
        });

        return this;
    }
1267307
private static Set<TypeMirror> nonPrivateDeclaredTypes(Types typeUtils, TypeMirror type) {
    if (type == null) {
      return new TypeMirrorSet();
    } else {
      Set<TypeMirror> declared = new TypeMirrorSet();
      declared.add(type);
      List<TypeElement> nestedTypes =
          ElementFilter.typesIn(typeUtils.asElement(type).getEnclosedElements());
      for (TypeElement nestedType : nestedTypes) {
        if (!nestedType.getModifiers().contains(PRIVATE)) {
          declared.add(nestedType.asType());
        }
      }
      for (TypeMirror supertype : typeUtils.directSupertypes(type)) {
        declared.addAll(nonPrivateDeclaredTypes(typeUtils, supertype));
      }
      return declared;
    }
  }
762154
static void validateExtends(EntityType entityType) {
    EntityType entityTypeExtends = entityType.getExtends();
    if (entityTypeExtends != null && !entityTypeExtends.isAbstract()) {
      throw new MolgenisValidationException(
          new ConstraintViolation(
              format(
                  "EntityType [%s] is not abstract; EntityType [%s] can't extend it",
                  entityTypeExtends.getId(), entityType.getId())));
    }
  }
843882
protected function checkValidTypeName($name)
    {
        if (in_array($name, ['Abstract', 'AbstractType', 'Generic'])) {
            return false;
        }
        if (
            strpos($name, '\AbstractType') !== false ||
            strpos($name, '/AbstractType') !== false
        ) {
            return false;
        }
        if (strpos($name, 'Trait') !== false) {
            return false;
        }

        return true;
    }
123529
function initCustomPointerTypemaps(typemapsdir) {
  return fs.readdirAsync(typemapsdir).then(function(dirs) {
    return Promise.all(_.map(dirs, function(dir) {
      // get all js*.i directives from class-specific subdirectories, to be parsed below for %typemaps directives
      return fs.readdirAsync(typemapsdir + '/' + dir).then(function(files) {
        var directive = _.find(files, function(fn) {
          return ((path.extname(fn) == '.i') && (path.basename(fn).search(/^js/) != -1));
        });
        var data = {};
        if (directive) {
          data[dir] = typemapsdir + '/' + dir + '/' + directive;
        }
        return data;
      }).catch(function(e) {
        // get all .i directives from top level directory, and parse for %array_class directives
        if (e.code == 'ENOTDIR') {
          var fn = dir;
          if (path.extname(fn) == '.i') {
            return fs.readFileAsync(typemapsdir + '/' + fn, 'utf8').then(function(directives) {
              var arraytypes = _.filter(directives.split(/\n/), function(line) {
                return (line.search(/^%array_class/) != -1);
              });
              _.each(arraytypes, function(arraytype) {
                var parsed = arraytype.match(/%array_class\(([A-Za-z0-9_]+)[\s]*,[\s]*([A-Za-z0-9_]+)\)/);
                if (parsed) {
                  var from = parsed[1];
                  var to = parsed[2];
                  xml2js.ARRAY_TYPEMAPS[from] = { arrayType: to, classes: [] };
                } else {
                  console.log('Incorrectly parsed array_class from ' + fn + ': ' + arraytype);
                }
              });
            });
          }
        } else {
          throw e;
        }
      });
    }));
  }).then(function(__directivesFiles) {
    // parse for %typemaps & %pointer_functions directives
    var _directivesFiles = _.filter(__directivesFiles, function(data) { return !_.isEmpty(data); });
    var directivesFiles = _.object(_.map(_directivesFiles, _.keys), _.flatten(_.map(_directivesFiles, _.values)));
    return Promise.all(_.map(directivesFiles, function(directivesFn, className) {
      return fs.readFileAsync(directivesFn, 'utf8').then(function(directives) {
        var typemaps = _.filter(directives.split(/\n/), function(line) {
          return (line.search(/^%typemap/) != -1);
        });
        _.each(typemaps, function(typemap) {
          var parsed = typemap.match(/%typemap\((in|out)\)[\s]+([A-Za-z0-9_]+[\s]*[\*])/);
          if (parsed) {
            var dir = parsed[1]; // TODO: ignored for now
            var type = normalizePointer(parsed[2]);
            var datatype = getPointerDataType(type);
            if (_.has(xml2js.ARRAY_TYPEMAPS, datatype)) {
              xml2js.ARRAY_TYPEMAPS[datatype].classes.push(className);
            } else {
              console.log('Ignored typemap from ' + directivesFn + ': ' + typemap.replace('{', '') + ' (no %array_class directive found for ' + datatype + ')');
            }
          } else {
            console.log('Ignored typemap from ' + directivesFn + ': ' + typemap.replace('{', '') + ' (only considering in/out typemaps of pointer types)');
          }
        });
        var ptrfns = _.filter(directives.split(/\n/), function(line) {
          return (line.search(/^%pointer_functions/) != -1);
        });
        _.each(ptrfns, function(ptrfn) {
          var parsed = ptrfn.match(/%pointer_functions\(([A-Za-z0-9_]+)[\s]*,[\s]*([A-Za-z0-9_]+)\)/);
          if (parsed) {
            var from = parsed[1];
            var to = parsed[2];
            if (!_.has(xml2js.POINTER_TYPEMAPS, className)) {
              xml2js.POINTER_TYPEMAPS[className] = {};
            }
            xml2js.POINTER_TYPEMAPS[className][from] = to;
          }
        });
      });
    }));
  });
}
1158542
function validateIfDeprecated (directives) {
  if (!directives.length) {
    return false
  }

  return directives.some(directive => directive.name.value === 'deprecated')
}
1343628
function extension (type) {
  if (!type || typeof type !== 'string') {
    return false
  }

  // TODO: use media-typer
  var match = EXTRACT_TYPE_REGEXP.exec(type)

  // get extensions
  var exts = match && exports.extensions[match[1].toLowerCase()]

  if (!exts || !exts.length) {
    return false
  }

  return exts[0]
}
1009334
private boolean isEligibleDefinitionSite(String name, Node definitionSite) {
    switch (definitionSite.getToken()) {
      case GETPROP:
      case MEMBER_FUNCTION_DEF:
      case STRING_KEY:
        break;

      default:
        // No other node types are supported.
        throw new IllegalArgumentException(definitionSite.toString());
    }

    // Exporting a method prevents rewrite.
    CodingConvention codingConvention = compiler.getCodingConvention();
    if (codingConvention.isExported(name)) {
      return false;
    }

    if (!isPrototypeMethodDefinition(definitionSite)) {
      return false;
    }

    return true;
  }
1229170
private function initTypeExtensions()
    {
        $this->typeExtensions = array();

        foreach ($this->loadTypeExtensions() as $extension) {
            if (!$extension instanceof JobTypeExtensionInterface) {
                throw new \InvalidArgumentException(sprintf('Extension %s should implements JobTypeExtensionInterface', get_class($extension)));
            }

            $type = $extension->getExtendedType();

            $this->typeExtensions[$type][] = $extension;
        }
    }
1050804
def v_type_extension(ctx, stmt):
    """"""
    (modulename, identifier) = stmt.keyword
    revision = stmt.i_extension_revision
    module = modulename_to_module(stmt.i_module, modulename, revision)
    if module is None:
        return
    if identifier not in module.i_extensions:
        if module.i_modulename == stmt.i_orig_module.i_modulename:
            # extension defined in current submodule
            if identifier not in stmt.i_orig_module.i_extensions:
                err_add(ctx.errors, stmt.pos, 'EXTENSION_NOT_DEFINED',
                        (identifier, module.arg))
                return
            else:
                stmt.i_extension = stmt.i_orig_module.i_extensions[identifier]
        else:
            err_add(ctx.errors, stmt.pos, 'EXTENSION_NOT_DEFINED',
                    (identifier, module.arg))
            return
    else:
        stmt.i_extension = module.i_extensions[identifier]
    ext_arg = stmt.i_extension.search_one('argument')
    if stmt.arg is not None and ext_arg is None:
        err_add(ctx.errors, stmt.pos, 'EXTENSION_ARGUMENT_PRESENT',
                identifier)
    elif stmt.arg is None and ext_arg is not None:
        err_add(ctx.errors, stmt.pos, 'EXTENSION_NO_ARGUMENT_PRESENT',
                identifier)
1330044
def parse_interface_type_extension(lexer: Lexer) -> Node:
    """"""
    start = lexer.token
    expect_keyword(lexer, "extend")
    expect_keyword(lexer, "interface")
    name = parse_name(lexer)
    directives = parse_directives(lexer, True)
    fields = parse_fields_definition(lexer)
    if not (directives or fields):
        raise unexpected(lexer)
    return Node(
        name=name, directives=directives, fields=fields, loc=loc(lexer, start)
    )
365308
protected function lexEnumTypeExtension(): EnumTypeExtensionNode
    {
        $start = $this->lexer->getToken();

        $this->expectKeyword(KeywordEnum::EXTEND);
        $this->expectKeyword(KeywordEnum::ENUM);

        $name       = $this->lexName();
        $directives = $this->lexDirectives();
        $values     = $this->lexEnumValuesDefinition();

        if (empty($directives) && empty($values)) {
            throw $this->unexpected();
        }

        return new EnumTypeExtensionNode($name, $directives, $values, $this->createLocation($start));
    }
825526
function ValidationExtension() {
    var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
        _ref$reject = _ref.reject,
        reject = _ref$reject === undefined ? false : _ref$reject;

    _classCallCheck(this, ValidationExtension);

    // Store configuration
    var _this = _possibleConstructorReturn(this, (ValidationExtension.__proto__ || Object.getPrototypeOf(ValidationExtension)).call(this, {
      onEntityInstantiate: true,
      onChangeDetected: true
    }));

    _this.rejectInvalidValues = reject;
    return _this;
  }
1356410
def visitTypeDirective(self, ctx: jsgParser.TypeDirectiveContext):
        
        self._context.directives.append('_CONTEXT.TYPE = "{}"'.format(as_token(ctx.name())))
        self._context.has_typeid = True
        self.visitChildren(ctx)