ace.define('ace/mode/error', function(require, exports, module) {
  const TextMode = require('ace/mode/text').Mode;
  const TextHighlightRules = require('ace/mode/text_highlight_rules')
    .TextHighlightRules;

  class ErrorMode extends TextMode {
    constructor() {
      super();
      this.$id = 'ace/mode/error';
      this.HighlightRules = ErrorHighlightRules;
    }
  }

  class ErrorHighlightRules extends TextHighlightRules {
    constructor() {
      super();
      this.$rules = {
        start: [
          {
            token: 'invalid',
            regex: /^(:?(:?Server|Network) )?Error:$/,
          },
          {
            token: ['markup.bold', 'invalid', 'markup.bold'],
            regex: /^([\w\-\/.~]+:[0-9]*:[0-9]*: )(error:)( .+)$/
          },
          {
            token: 'markup.bold.keyword',
            regex: /~*\^~*$/,
          },
        ],
      };
    }
  }

  exports.Mode = ErrorMode;
});

ace.define('ace/mode/bytes', function(require, exports, module) {
  const TextMode = require('ace/mode/text').Mode;
  const TextHighlightRules = require('ace/mode/text_highlight_rules')
    .TextHighlightRules;

  class BytesMode extends TextMode {
    constructor() {
      super();
      this.$id = 'ace/mode/bytes';
      this.HighlightRules = BytesHighlightRules;
      this.lineCommentStart = '//';
    }
  }

  class BytesHighlightRules extends TextHighlightRules {
    constructor() {
      super();
      this.$rules = {
        start: [
          {
            token: 'comment',
            regex: '//.*$',
          },
          {
            token: 'string',
            regex: /"(?:[^"\\]|\\.)*?"/,
          },
          {
            token: ['text', 'variable'],
            regex: /^(\s*)([0-9a-fA-F]+:)/,
          },
          {
            token: ['constant.numeric', 'keyword.operator'],
            regex: /((?:-)?(?:0b[01]+|0o[0-7]+|0x[0-9a-fA-F]+|[0-9]+))([ui](?:8|16|32|64))\b/,
          },
        ],
      };
    }
  }

  exports.Mode = BytesMode;
});

ace.define('ace/mode/fidl', function(require, exports, module) {
  const TextMode = require('ace/mode/text').Mode;
  const TextHighlightRules = require('ace/mode/text_highlight_rules')
    .TextHighlightRules;
  const MatchingBraceOutdent = require('ace/mode/matching_brace_outdent')
    .MatchingBraceOutdent;
  const CstyleBehaviour = require('ace/mode/behaviour/cstyle').CstyleBehaviour;
  const CstyleFoldMode = require('ace/mode/folding/cstyle').FoldMode;

  class FidlMode extends TextMode {
    constructor() {
      super();
      this.$id = 'ace/mode/fidl';
      this.HighlightRules = FidlHighlightRules;
      this.$outdent = new MatchingBraceOutdent();
      this.$behaviour = new CstyleBehaviour();
      this.foldingRules = new CstyleFoldMode();
      this.lineCommentStart = '//';
    }

    getNextLineIndent(state, line, tab) {
      let indent = line.match(/^\s*/)[0];
      const tokens = this.getTokenizer().getLineTokens(line, state).tokens;
      if (tokens.length && tokens[tokens.length - 1].type === 'comment') {
        return indent;
      }
      if (state === 'start') {
        const match = line.match(/^.*[\{\(\[]\s*$/);
        if (match) {
          indent += tab;
        }
      }
      return indent;
    }

    checkOutdent(state, line, input) {
      return this.$outdent.checkOutdent(line, input);
    }

    autoOutdent(state, doc, row) {
      this.$outdent.autoOutdent(doc, row);
    }
  }

  class FidlHighlightRules extends TextHighlightRules {
    constructor() {
      super();
      this.$rules = {
        start: [
          {
            token: 'comment',
            regex: '//.*$',
          },
          {
            token: 'string',
            regex: /"(?:[^"\\]|\\.)*?"/,
          },
          {
            token: 'keyword',
            regex: /\b(?:alias|as|bits|box|compose|const|enum|flexible|library|optional|protocol|reserved|resource|strict|struct|table|type|union|using)\b/,
          },
          {
            token: 'support.type',
            regex: /\b(?:bool|int8|int16|int32|int64|uint8|uint16|uint32|uint64|float32|float64|array|vector|string|byte|bytes|client_end|server_end)\b/,
          },
          {
            token: ['text', 'keyword'],
            regex: /(\)\s*)(error)\b/,
          },
          {
            token: 'keyword.operator',
            regex: /->|:/,
          },
          {
            token: 'support.type',
            regex: /<|>/,
          },
          {
            token: 'constant.language',
            regex: /\b(?:true|false)\b/,
          },
          {
            token: 'constant.numeric',
            regex: /\b0[xX][0-9a-fA-F]+\b/,
          },
          {
            token: 'constant.numeric',
            regex: /\b[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/,
          },
          {
            token: 'support.constant',
            regex: /\@[a-zA-Z](?:[a-zA-Z0-9_]*[a-zA-Z0-9])?/,
          },
          {
            token: ['entity.name.function', 'text'],
            regex: /([a-zA-Z](?:[a-zA-Z0-9_]*[a-zA-Z0-9])?)(\()/,
          },
        ],
      };
    }
  }

  exports.Mode = FidlMode;
});
