13af6ab5fSopenharmony_ci#!/usr/bin/env ruby
23af6ab5fSopenharmony_ci# Copyright (c) 2021-2024 Huawei Device Co., Ltd.
33af6ab5fSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
43af6ab5fSopenharmony_ci# you may not use this file except in compliance with the License.
53af6ab5fSopenharmony_ci# You may obtain a copy of the License at
63af6ab5fSopenharmony_ci#
73af6ab5fSopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0
83af6ab5fSopenharmony_ci#
93af6ab5fSopenharmony_ci# Unless required by applicable law or agreed to in writing, software
103af6ab5fSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
113af6ab5fSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123af6ab5fSopenharmony_ci# See the License for the specific language governing permissions and
133af6ab5fSopenharmony_ci# limitations under the License.
143af6ab5fSopenharmony_ci
153af6ab5fSopenharmony_cirequire 'ostruct'
163af6ab5fSopenharmony_cirequire 'set'
173af6ab5fSopenharmony_cirequire 'delegate'
183af6ab5fSopenharmony_ci
193af6ab5fSopenharmony_cimodule Keywords
203af6ab5fSopenharmony_ci  module_function
213af6ab5fSopenharmony_ci
223af6ab5fSopenharmony_ci  def extensions
233af6ab5fSopenharmony_ci    @extensions
243af6ab5fSopenharmony_ci  end
253af6ab5fSopenharmony_ci
263af6ab5fSopenharmony_ci  def build_tree(keys)
273af6ab5fSopenharmony_ci    tree = Hash.new()
283af6ab5fSopenharmony_ci    offset = 0
293af6ab5fSopenharmony_ci
303af6ab5fSopenharmony_ci    while true
313af6ab5fSopenharmony_ci      has_more = false
323af6ab5fSopenharmony_ci      keys.each do |key|
333af6ab5fSopenharmony_ci          if key.length < offset + 1
343af6ab5fSopenharmony_ci            next
353af6ab5fSopenharmony_ci          end
363af6ab5fSopenharmony_ci
373af6ab5fSopenharmony_ci        has_more = true
383af6ab5fSopenharmony_ci        func_name = key[0..offset];
393af6ab5fSopenharmony_ci        if tree.has_key?(func_name)
403af6ab5fSopenharmony_ci          tree[func_name].add(key[offset + 1])
413af6ab5fSopenharmony_ci        else
423af6ab5fSopenharmony_ci          tree[func_name] = Set[key[offset + 1]]
433af6ab5fSopenharmony_ci        end
443af6ab5fSopenharmony_ci      end
453af6ab5fSopenharmony_ci
463af6ab5fSopenharmony_ci      if has_more
473af6ab5fSopenharmony_ci        offset += 1
483af6ab5fSopenharmony_ci        next
493af6ab5fSopenharmony_ci      end
503af6ab5fSopenharmony_ci      break
513af6ab5fSopenharmony_ci    end
523af6ab5fSopenharmony_ci
533af6ab5fSopenharmony_ci    return tree
543af6ab5fSopenharmony_ci  end
553af6ab5fSopenharmony_ci
563af6ab5fSopenharmony_ci  def wrap_data(data)
573af6ab5fSopenharmony_ci    @extensions = Hash.new()
583af6ab5fSopenharmony_ci
593af6ab5fSopenharmony_ci    if !data || !data.extensions || !data.keywords
603af6ab5fSopenharmony_ci      return
613af6ab5fSopenharmony_ci    end
623af6ab5fSopenharmony_ci
633af6ab5fSopenharmony_ci    data.extensions.each do |extension|
643af6ab5fSopenharmony_ci      @extensions[extension.name] = Hash.new()
653af6ab5fSopenharmony_ci      all_words = data.keywords.select do |desc|
663af6ab5fSopenharmony_ci        s_kw = Set.new(desc&.keyword)
673af6ab5fSopenharmony_ci        groups = [s_kw, Set.new(desc&.keyword_like), Set.new(desc&.custom_handler)]
683af6ab5fSopenharmony_ci        groups.combination(2).each { |a,b| raise "Conflicting keyword type" unless (a & b).empty? }
693af6ab5fSopenharmony_ci
703af6ab5fSopenharmony_ci        active = Set.new();
713af6ab5fSopenharmony_ci        groups.each { |group| active.merge(group) }
723af6ab5fSopenharmony_ci
733af6ab5fSopenharmony_ci        raise "Unknown extension" unless active.subset?(Set.new(data.extensions.map { |ext| ext.name }))
743af6ab5fSopenharmony_ci        active.include? extension.name
753af6ab5fSopenharmony_ci      end
763af6ab5fSopenharmony_ci
773af6ab5fSopenharmony_ci      keywords = data.keywords.select do |desc|
783af6ab5fSopenharmony_ci        desc&.keyword&.include? extension.name or desc&.custom_handler&.include? extension.name
793af6ab5fSopenharmony_ci      end
803af6ab5fSopenharmony_ci
813af6ab5fSopenharmony_ci      @extensions[extension.name]['keywords'] = keywords
823af6ab5fSopenharmony_ci      @extensions[extension.name]['keyword_starts'] = Set.new(keywords.map { |desc| desc.name[0] })
833af6ab5fSopenharmony_ci      @extensions[extension.name]['all_words'] = all_words
843af6ab5fSopenharmony_ci      @extensions[extension.name]['all_word_starts'] = Set.new(all_words.map { |desc| desc.name[0] })
853af6ab5fSopenharmony_ci      @extensions[extension.name]['tree'] = build_tree(all_words.map { |desc| desc.name })
863af6ab5fSopenharmony_ci    end
873af6ab5fSopenharmony_ci  end
883af6ab5fSopenharmony_ciend
893af6ab5fSopenharmony_ci
903af6ab5fSopenharmony_cidef Gen.on_require(data)
913af6ab5fSopenharmony_ci  Keywords.wrap_data(data)
923af6ab5fSopenharmony_ciend
933af6ab5fSopenharmony_ci
94