// -*- mode: js; indent-tabs-mode: nil; js-basic-offset: 4 -*-
//
// This file is part of Genie
//
// Copyright 2019-2020 The Board of Trustees of the Leland Stanford Junior University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: Giovanni Campagna <gcampagn@cs.stanford.edu>

import { Ast, Type } from 'thingtalk';
import * as C from './ast_manip';
import ThingpediaLoader from './load-thingpedia';
import type * as $Genie from "genie-toolkit";
export default async function($runtime : typeof $Genie.SentenceGeneratorRuntime, $ttUtils : typeof $Genie.ThingTalkUtils, $options : $Genie.SentenceGeneratorTypes.GrammarOptions, $locale : $Genie.I18n.LanguagePack, $grammar : $Genie.SentenceGenerator<any, any>, $loader : ThingpediaLoader) : Promise<void> {

const MAX_SMALL_INTEGER = 12;
   for (let i = 0; i <= MAX_SMALL_INTEGER; i++) {
       $grammar.declareSymbol("constant_Number");
       $grammar.addRule("constant_Number", [String(i)], (($0 : undefined) : (Ast.NumberValue)|null => new Ast.Value.Number(i)), C.entityOrNumberValueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_String");
   $grammar.addConstants("constant_String", "QUOTED_STRING", Type.String, C.valueKeyFn, {  });
   $grammar.declareSymbol("constant_Entity__tt__url");
   $grammar.addConstants("constant_Entity__tt__url", "URL", new Type.Entity('tt:url'), C.entityOrNumberValueKeyFn, {  });
   $grammar.declareSymbol("constant_Entity__tt__username");
   $grammar.addConstants("constant_Entity__tt__username", "USERNAME", new Type.Entity('tt:username'), C.entityOrNumberValueKeyFn, {  });
   $grammar.declareSymbol("constant_Entity__tt__hashtag");
   $grammar.addConstants("constant_Entity__tt__hashtag", "HASHTAG", new Type.Entity('tt:hashtag'), C.entityOrNumberValueKeyFn, {  });
   $grammar.declareSymbol("constant_Entity__tt__phone_number");
   $grammar.addConstants("constant_Entity__tt__phone_number", "PHONE_NUMBER", new Type.Entity('tt:phone_number'), C.entityOrNumberValueKeyFn, {  });
   $grammar.declareSymbol("constant_Entity__tt__email_address");
   $grammar.addConstants("constant_Entity__tt__email_address", "EMAIL_ADDRESS", new Type.Entity('tt:email_address'), C.entityOrNumberValueKeyFn, {  });
   $grammar.declareSymbol("constant_Entity__tt__path_name");
   $grammar.addConstants("constant_Entity__tt__path_name", "PATH_NAME", new Type.Entity('tt:path_name'), C.entityOrNumberValueKeyFn, {  });
   $grammar.declareSymbol("constant_Number");
   $grammar.addConstants("constant_Number", "NUMBER", Type.Number, C.entityOrNumberValueKeyFn, {  });
   $grammar.declareSymbol("constant_Currency");
   $grammar.addConstants("constant_Currency", "CURRENCY", Type.Currency, C.valueKeyFn, {  });
   $grammar.declareSymbol("constant_Time");
   $grammar.addConstants("constant_Time", "TIME", Type.Time, C.valueKeyFn, {  });
   $grammar.declareSymbol("constant_Date");
   $grammar.addConstants("constant_Date", "DATE", Type.Date, C.valueKeyFn, {  });
   $grammar.declareSymbol("constant_Location");
   $grammar.addConstants("constant_Location", "LOCATION", Type.Location, C.valueKeyFn, {  });
   $grammar.declareSymbol("constant_Entity__tt__picture");
   $grammar.declareSymbol("constant_Entity__tt__function");
   $grammar.declareSymbol("constant_Entity__tt__program");
   $grammar.declareSymbol("constant_Entity__tt__device");
   $grammar.declareSymbol("constant_Boolean");
   $grammar.declareSymbol("constant_RecurrentTimeSpecification");
   $grammar.declareSymbol("constant_Measure_ms");
   if ($options.flags.inference) {
       $grammar.addConstants("constant_Measure_ms", "MEASURE_ms", new Type.Measure('ms'), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_byte");
   if ($options.flags.inference) {
       $grammar.addConstants("constant_Measure_byte", "MEASURE_byte", new Type.Measure('byte'), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_kg");
   if ($options.flags.inference) {
       $grammar.addConstants("constant_Measure_kg", "MEASURE_kg", new Type.Measure('kg'), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_C");
   if ($options.flags.inference) {
       $grammar.addConstants("constant_Measure_C", "MEASURE_C", new Type.Measure('C'), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_m");
   if ($options.flags.inference) {
       $grammar.addConstants("constant_Measure_m", "MEASURE_m", new Type.Measure('m'), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_m2");
   if ($options.flags.inference) {
       $grammar.addConstants("constant_Measure_m2", "MEASURE_m2", new Type.Measure('m2'), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_m3");
   if ($options.flags.inference) {
       $grammar.addConstants("constant_Measure_m3", "MEASURE_m3", new Type.Measure('m3'), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_m2");
   if ($options.flags.inference) {
       $grammar.addConstants("constant_Measure_m2", "MEASURE_m2", new Type.Measure('m2'), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_m3");
   if ($options.flags.inference) {
       $grammar.addConstants("constant_Measure_m3", "MEASURE_m3", new Type.Measure('m3'), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_mps");
   if ($options.flags.inference) {
       $grammar.addConstants("constant_Measure_mps", "MEASURE_mps", new Type.Measure('mps'), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_Pa");
   if ($options.flags.inference) {
       $grammar.addConstants("constant_Measure_Pa", "MEASURE_Pa", new Type.Measure('Pa'), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_kcal");
   if ($options.flags.inference) {
       $grammar.addConstants("constant_Measure_kcal", "MEASURE_kcal", new Type.Measure('kcal'), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_W");
   if ($options.flags.inference) {
       $grammar.addConstants("constant_Measure_W", "MEASURE_W", new Type.Measure('W'), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_lx");
   if ($options.flags.inference) {
       $grammar.addConstants("constant_Measure_lx", "MEASURE_lx", new Type.Measure('lx'), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_lm");
   if ($options.flags.inference) {
       $grammar.addConstants("constant_Measure_lm", "MEASURE_lm", new Type.Measure('lm'), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_dB");
   if ($options.flags.inference) {
       $grammar.addConstants("constant_Measure_dB", "MEASURE_dB", new Type.Measure('dB'), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_dBm");
   if ($options.flags.inference) {
       $grammar.addConstants("constant_Measure_dBm", "MEASURE_dBm", new Type.Measure('byte'), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Any");
   if (!$options.flags.unbalanced) {
       $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_String", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { repeat: (true), identity: (true) });
   }
   if ($options.flags.unbalanced) {
       $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_String", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   }
   $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Entity__tt__picture", undefined)], (($0 : Ast.EntityValue) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Entity__tt__username", undefined)], (($0 : Ast.EntityValue) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Entity__tt__hashtag", undefined)], (($0 : Ast.EntityValue) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Entity__tt__phone_number", undefined)], (($0 : Ast.EntityValue) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Entity__tt__email_address", undefined)], (($0 : Ast.EntityValue) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Entity__tt__path_name", undefined)], (($0 : Ast.EntityValue) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Number", undefined)], (($0 : Ast.NumberValue) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Time", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Location", undefined)], (($0 : Ast.LocationValue) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Currency", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   if (!$options.flags.turking) {
       $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Entity__tt__url", undefined)], (($0 : Ast.EntityValue) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
       $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Date", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
       $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Measure_ms", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
       $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Measure_byte", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
       $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Measure_mps", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
       $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Measure_m", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
       $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Measure_m2", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
       $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Measure_m3", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
       $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Measure_C", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
       $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Measure_kg", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
       $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Measure_Pa", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
       $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Measure_kcal", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
       $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Measure_W", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
       $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Measure_lx", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
       $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Measure_lm", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
       $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Measure_dB", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
       $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Measure_dBm", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
       $grammar.addRule("constant_Any", [new $runtime.NonTerminal("constant_Boolean", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   }
   $grammar.declareSymbol("constant_Numeric");
   $grammar.addRule("constant_Numeric", [new $runtime.NonTerminal("constant_Number", undefined)], (($0 : Ast.NumberValue) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   $grammar.addRule("constant_Numeric", [new $runtime.NonTerminal("constant_Currency", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   $grammar.addRule("constant_Numeric", [new $runtime.NonTerminal("constant_Measure_ms", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   $grammar.addRule("constant_Numeric", [new $runtime.NonTerminal("constant_Measure_byte", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   $grammar.addRule("constant_Numeric", [new $runtime.NonTerminal("constant_Measure_mps", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   $grammar.addRule("constant_Numeric", [new $runtime.NonTerminal("constant_Measure_m", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   $grammar.addRule("constant_Numeric", [new $runtime.NonTerminal("constant_Measure_m2", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   $grammar.addRule("constant_Numeric", [new $runtime.NonTerminal("constant_Measure_m3", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   $grammar.addRule("constant_Numeric", [new $runtime.NonTerminal("constant_Measure_C", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   $grammar.addRule("constant_Numeric", [new $runtime.NonTerminal("constant_Measure_kg", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   $grammar.addRule("constant_Numeric", [new $runtime.NonTerminal("constant_Measure_Pa", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   $grammar.addRule("constant_Numeric", [new $runtime.NonTerminal("constant_Measure_kcal", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   $grammar.addRule("constant_Numeric", [new $runtime.NonTerminal("constant_Measure_W", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   $grammar.addRule("constant_Numeric", [new $runtime.NonTerminal("constant_Measure_lx", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   $grammar.addRule("constant_Numeric", [new $runtime.NonTerminal("constant_Measure_lm", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   $grammar.addRule("constant_Numeric", [new $runtime.NonTerminal("constant_Measure_dB", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
   $grammar.addRule("constant_Numeric", [new $runtime.NonTerminal("constant_Measure_dBm", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
};
