text: /**
   * @license
   * Visual Blocks Editor
   *
   * Copyright 2017 Google Inc.
   * https://developers.google.com/blockly/
   *
   * 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.
   */
  
  /**
   * @fileoverview Variable getter field.  Appears as a label but has a variable
   *     picker in the right-click menu.
   * @author fenichel@google.com (Rachel Fenichel)
   */
  'use strict';
  
  goog.provide('Blockly.FieldVariableGetter');
  
  goog.require('Blockly.Field');
  
  
  /**
   * Class for a variable getter field.
   * @param {string} text The initial content of the field.
   * @param {string} name Optional CSS class for the field's text.
   * @param {string} opt_varType The type of variable this field is associated with.
   * @extends {Blockly.FieldLabel}
   * @constructor
   *
   */
  Blockly.FieldVariableGetter = function(text, name, opt_varType) {
    this.size_ = new goog.math.Size(Blockly.BlockSvg.FIELD_WIDTH,
        Blockly.BlockSvg.FIELD_HEIGHT);
    this.text_ = text;
  
    /**
     * Maximum characters of text to display before adding an ellipsis.
     * Same for strings and numbers.
     * @type {number}
     */
    this.maxDisplayLength = Blockly.BlockSvg.MAX_DISPLAY_LENGTH;
  
    this.name_ = name;
    this.variableType_ = opt_varType ? opt_varType : '';
  };
  goog.inherits(Blockly.FieldVariableGetter, Blockly.Field);
  
  /**
   * Construct a FieldVariableGetter from a JSON arg object,
   * dereferencing any string table references.
   * @param {!Object} options A JSON object with options (variable,
   *                          variableTypes, and defaultType).
   * @returns {!Blockly.FieldVariableGetter} The new field instance.
   * @package
   * @nocollapse
   */
  Blockly.FieldVariableGetter.fromJson = function(options) {
    var varname = Blockly.utils.replaceMessageReferences(options['text']);
    return new Blockly.FieldVariableGetter(varname, options['name'],
        options['class'], options['variableType']);
  };
  
  /**
   * Editable fields usually show some sort of UI for the user to change them.
   * This field should be serialized, but only edited programmatically.
   * @type {boolean}
   * @public
   */
  Blockly.FieldVariableGetter.prototype.EDITABLE = false;
  
  /**
   * Serializable fields are saved by the XML renderer, non-serializable fields
   * are not.  This field should be serialized, but only edited programmatically.
   * @type {boolean}
   * @public
   */
  Blockly.FieldVariableGetter.prototype.SERIALIZABLE = true;
  
  /**
   * Install this field on a block.
   */
  Blockly.FieldVariableGetter.prototype.init = function() {
    if (this.fieldGroup_) {
      // Field has already been initialized once.
      return;
    }
    Blockly.FieldVariableGetter.superClass_.init.call(this);
    if (this.variable_) {
      return; // Initialization already happened.
    }
    this.workspace_ = this.sourceBlock_.workspace;
    var variable = Blockly.Variables.getOrCreateVariablePackage(
        this.workspace_, null, this.text_, this.variableType_);
    this.setValue(variable.getId());
  };
  
  /**
   * Get the variable's ID.
   * @return {string} Current variable's ID.
   */
  Blockly.FieldVariableGetter.prototype.getValue = function() {
    return this.variable_ ? this.variable_.getId() : '';
  };
  
  /**
   * Get the text from this field.
   * @return {string} Current text.
   */
  Blockly.FieldVariableGetter.prototype.getText = function() {
    return this.variable_ ? this.variable_.name : '';
  };
  
  /**
   * Get the variable model for the variable associated with this field.
   * Not guaranteed to be in the variable map on the workspace (e.g. if accessed
   * after the variable has been deleted).
   * @return {?Blockly.VariableModel} the selected variable, or null if none was
   *     selected.
   * @package
   */
  Blockly.FieldVariableGetter.prototype.getVariable = function() {
    return this.variable_;
  };
  
  Blockly.FieldVariableGetter.prototype.setValue = function(id) {
    // What do I do when id is null?  That happens when undoing a change event
    // for the first time the value was set.
    var workspace = this.sourceBlock_.workspace;
    var variable = Blockly.Variables.getVariable(workspace, id);
  
    if (!variable) {
      throw new Error('Variable id doesn\'t point to a real variable!  ID was ' +
          id);
    }
  
    if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
      var oldValue = this.variable_ ? this.variable_.getId() : null;
      Blockly.Events.fire(new Blockly.Events.BlockChange(
          this.sourceBlock_, 'field', this.name, oldValue, variable.getId()));
    }
    this.variable_ = variable;
    this.value_ = id;
    this.setText(variable.name);
  };
  
  /**
   * This field is editable, but only through the right-click menu.
   * @private
   */
  Blockly.FieldVariableGetter.prototype.showEditor_ = function() {
    // nop.
  };
  
  /**
   * Add or remove the UI indicating if this field is editable or not.
   * This field is editable, but only through the right-click menu.
   * Suppress default editable behaviour.
   */
  Blockly.FieldVariableGetter.prototype.updateEditable = function() {
    // nop.
  };
  
  /**
   * Whether this field references any Blockly variables.  If true it may need to
   * be handled differently during serialization and deserialization.  Subclasses
   * may override this.
   * @return {boolean} True if this field has any variable references.
   * @package
   */
  Blockly.FieldVariableGetter.prototype.referencesVariables = function() {
    return true;
  };
  
  Blockly.Field.register('field_variable_getter', Blockly.FieldVariableGetter);
  