/*
 * Copyright (c) 2011 Google Inc.
 *
 * All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse
 * Public License v1.0 which accompanies this distribution, and is available at
 *
 * http://www.eclipse.org/legal/epl-v10.html
 */
package com.google.eclipse.protobuf.ui.contentassist;

import static com.google.common.collect.Lists.newArrayList;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.CLOSING_BRACKET;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.DEFAULT;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.EQUAL;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.FALSE;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.NAN;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.OPENING_BRACKET;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.OPENING_CURLY_BRACKET;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.SYNTAX;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.TRUE;
import static com.google.eclipse.protobuf.protobuf.ModifierEnum.OPTIONAL;
import static com.google.eclipse.protobuf.protobuf.ModifierEnum.REPEATED;
import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.LITERAL;
import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.OPTION;
import static com.google.eclipse.protobuf.ui.grammar.CompoundElement.DEFAULT_EQUAL;
import static com.google.eclipse.protobuf.ui.grammar.CompoundElement.DEFAULT_EQUAL_IN_BRACKETS;
import static com.google.eclipse.protobuf.ui.grammar.CompoundElement.DEFAULT_EQUAL_STRING;
import static com.google.eclipse.protobuf.ui.grammar.CompoundElement.DEFAULT_EQUAL_STRING_IN_BRACKETS;
import static com.google.eclipse.protobuf.ui.grammar.CompoundElement.EMPTY_STRING;
import static com.google.eclipse.protobuf.ui.grammar.CompoundElement.EQUAL_PROTO2_IN_QUOTES;
import static com.google.eclipse.protobuf.ui.grammar.CompoundElement.EQUAL_PROTO3_IN_QUOTES;
import static com.google.eclipse.protobuf.ui.grammar.CompoundElement.PROTO2_IN_QUOTES;
import static com.google.eclipse.protobuf.ui.grammar.CompoundElement.PROTO3_IN_QUOTES;
import static com.google.eclipse.protobuf.util.CommonWords.space;
import static java.lang.String.valueOf;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptySet;
import static org.eclipse.xtext.EcoreUtil2.getAllContentsOfType;
import static org.eclipse.xtext.util.Strings.isEmpty;
import static org.eclipse.xtext.util.Strings.toFirstLower;

import com.google.eclipse.protobuf.grammar.CommonKeyword;
import com.google.eclipse.protobuf.model.util.IndexedElements;
import com.google.eclipse.protobuf.model.util.Literals;
import com.google.eclipse.protobuf.model.util.MessageFields;
import com.google.eclipse.protobuf.model.util.Options;
import com.google.eclipse.protobuf.protobuf.AbstractCustomOption;
import com.google.eclipse.protobuf.protobuf.AbstractOption;
import com.google.eclipse.protobuf.protobuf.ComplexValue;
import com.google.eclipse.protobuf.protobuf.CustomFieldOption;
import com.google.eclipse.protobuf.protobuf.CustomOption;
import com.google.eclipse.protobuf.protobuf.DefaultValueFieldOption;
import com.google.eclipse.protobuf.protobuf.Enum;
import com.google.eclipse.protobuf.protobuf.FieldName;
import com.google.eclipse.protobuf.protobuf.FieldOption;
import com.google.eclipse.protobuf.protobuf.IndexedElement;
import com.google.eclipse.protobuf.protobuf.Literal;
import com.google.eclipse.protobuf.protobuf.MessageField;
import com.google.eclipse.protobuf.protobuf.ModifierEnum;
import com.google.eclipse.protobuf.protobuf.NativeFieldOption;
import com.google.eclipse.protobuf.protobuf.NativeOption;
import com.google.eclipse.protobuf.protobuf.Option;
import com.google.eclipse.protobuf.protobuf.Rpc;
import com.google.eclipse.protobuf.protobuf.SimpleValueField;
import com.google.eclipse.protobuf.protobuf.Stream;
import com.google.eclipse.protobuf.protobuf.TypeExtension;
import com.google.eclipse.protobuf.scoping.ProtoDescriptor;
import com.google.eclipse.protobuf.scoping.ProtoDescriptorProvider;
import com.google.eclipse.protobuf.scoping.ProtobufScopeProvider;
import com.google.eclipse.protobuf.scoping.ScopeProvider;
import com.google.eclipse.protobuf.ui.grammar.CompoundElement;
import com.google.eclipse.protobuf.ui.labeling.Images;
import com.google.eclipse.protobuf.util.EResources;
import com.google.inject.Inject;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Image;
import org.eclipse.xtext.Assignment;
import org.eclipse.xtext.Keyword;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.ui.PluginImageHelper;
import org.eclipse.xtext.ui.editor.contentassist.ConfigurableCompletionProposal;
import org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext;
import org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor;

import java.util.Collection;
import java.util.List;


/**
 * @author alruiz@google.com (Alex Ruiz)
 *
 * @see <a href="http://www.eclipse.org/Xtext/documentation/latest/xtext.html#contentAssist">Xtext Content Assist</a>
 */
public class ProtobufProposalProvider extends AbstractProtobufProposalProvider {
  @Inject private IEObjectDescriptionChooser descriptionChooser;
  @Inject private ProtoDescriptorProvider descriptorProvider;
  @Inject private Images images;
  @Inject private IndexedElements indexedElements;
  @Inject private PluginImageHelper imageHelper;
  @Inject private Literals literals;
  @Inject private MessageFields messageFields;
  @Inject private Options options;

  @Override public void completeProtobuf_Syntax(EObject model, Assignment assignment, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {}

  @Override public void completeSyntax_Name(EObject model, Assignment assignment, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    proposeAndAccept(PROTO2_IN_QUOTES, context, acceptor);
    proposeAndAccept(PROTO3_IN_QUOTES, context, acceptor);
  }

  @Override public void complete_Syntax(EObject model, RuleCall ruleCall, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    String proposal = SYNTAX + space() + EQUAL_PROTO2_IN_QUOTES;
    proposeAndAccept(proposal, imageHelper.getImage(images.imageFor(SYNTAX)), context, acceptor);

    proposal = SYNTAX + space() + EQUAL_PROTO3_IN_QUOTES;
    proposeAndAccept(proposal, imageHelper.getImage(images.imageFor(SYNTAX)), context, acceptor);
  }

  @Override public void completeComplexTypeLink_Target(EObject model, Assignment assignment,
      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
    if (model instanceof MessageField) {
      Collection<IEObjectDescription> scope = scopeProvider().potentialComplexTypesFor((MessageField) model);
      for (IEObjectDescription d : descriptionChooser.shortestQualifiedNamesIn(scope)) {
        Image image = imageHelper.getImage(images.imageFor(d.getEObjectOrProxy()));
        proposeAndAccept(d, image, context, acceptor);
      }
    }
  }

  @Override public void completeExtensibleTypeLink_Target(EObject model, Assignment assignment,
      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
    Collection<IEObjectDescription> scope = emptySet();
    if (model instanceof TypeExtension) {
      TypeExtension typeExtension = (TypeExtension) model;
      scope = scopeProvider().potentialExtensibleTypesFor(typeExtension);
    }
    for (IEObjectDescription d : descriptionChooser.shortestQualifiedNamesIn(scope)) {
      Image image = imageHelper.getImage(images.imageFor(d.getEObjectOrProxy()));
      proposeAndAccept(d, image, context, acceptor);
    }
  }

  @Override public void completeMessageLink_Target(EObject model, Assignment assignment, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    Collection<IEObjectDescription> scope = emptySet();
    if (model instanceof Rpc) {
      Rpc rpc = (Rpc) model;
      scope = scopeProvider().potentialMessagesFor(rpc);
    }
    if (model instanceof Stream) {
      Stream stream = (Stream) model;
      scope = scopeProvider().potentialMessagesFor(stream);
    }
    for (IEObjectDescription d : descriptionChooser.shortestQualifiedNamesIn(scope)) {
      Image image = imageHelper.getImage(images.imageFor(d.getEObjectOrProxy()));
      proposeAndAccept(d, image, context, acceptor);
    }
  }

  @Override public void completeNativeOption_Source(EObject model, Assignment assignment,
      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
    ProtoDescriptor descriptor =
        descriptorProvider.primaryDescriptor(EResources.getProjectOf(model.eResource()));
    Collection<MessageField> optionProperties = descriptor.availableOptionsFor(model);
    if (!optionProperties.isEmpty()) {
      proposeOptions(optionProperties, context, acceptor);
    }
  }

  private void proposeOptions(Collection<MessageField> optionSources, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    for (MessageField source : optionSources) {
      proposeOption(source, context, acceptor);
    }
  }

  @Override public void completeNativeOption_Value(EObject model, Assignment assignment,
      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
    NativeOption option = (NativeOption) model;
    MessageField optionSource = (MessageField) options.rootSourceOf(option);
    if (optionSource == null) {
      return;
    }
    ProtoDescriptor descriptor =
        descriptorProvider.primaryDescriptor(EResources.getProjectOf(model.eResource()));
    Enum enumType = descriptor.enumTypeOf(optionSource);
    if (enumType != null) {
      proposeAndAccept(enumType, context, acceptor);
      return;
    }
    proposePrimitiveValues(optionSource, context, acceptor);
  }

  @Override public void complete_ID(EObject model, RuleCall ruleCall, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {}

  @Override public void complete_CHUNK(EObject model, RuleCall ruleCall, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {}

  @Override public void completeKeyword(Keyword keyword, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    if (keyword == null) {
      return;
    }
    boolean proposalWasHandledAlready = completeKeyword(keyword.getValue(), context, acceptor);
    if (proposalWasHandledAlready) {
      return;
    }
    super.completeKeyword(keyword, context, acceptor);
  }

  private boolean completeKeyword(String keyword, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
    if (isLastWordFromCaretPositionEqualTo(keyword, context)) {
      return true;
    }
    if (EQUAL.hasValue(keyword)) {
      EObject grammarElement = context.getLastCompleteNode().getGrammarElement();
      if (isKeyword(grammarElement, SYNTAX)) {
        proposeEqualProto2(context, acceptor);
        proposeEqualProto3(context, acceptor);
      }
      return true;
    }
    if (OPENING_BRACKET.hasValue(keyword)) {
      return proposeOpeningBracket(context, acceptor);
    }
    if (OPENING_CURLY_BRACKET.hasValue(keyword)) {
      EObject model = context.getCurrentModel();
      return model instanceof Option || model instanceof ComplexValue;
    }
    if (TRUE.hasValue(keyword) || FALSE.hasValue(keyword)) {
      if (isBoolProposalValid(context)) {
        proposeBooleanValues(context, acceptor);
      }
      return true;
    }
    if (NAN.hasValue(keyword)) {
      if (isNanProposalValid(context)) {
        proposeAndAccept(keyword.toString(), context, acceptor);
      }
      return true;
    }
    // remove keyword proposals when current node is "]". At this position we
    // only accept "default" or field options.
    return context.getCurrentNode().getText().equals(CLOSING_BRACKET.toString());
  }

  private boolean isLastWordFromCaretPositionEqualTo(String word, ContentAssistContext context) {
    StyledText styledText = context.getViewer().getTextWidget();
    int valueLength = word.length();
    int start = styledText.getCaretOffset() - valueLength;
    if (start < 0) {
      return false;
    }
    String previousWord = styledText.getTextRange(start, valueLength);
    return word.equals(previousWord);
  }

  private boolean isKeyword(EObject object, CommonKeyword keyword) {
    return object instanceof Keyword && keyword.hasValue(((Keyword) object).getValue());
  }

  private void proposeEqualProto2(ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
    proposeAndAccept(EQUAL_PROTO2_IN_QUOTES, context, acceptor);
  }

  private void proposeEqualProto3(ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
    proposeAndAccept(EQUAL_PROTO3_IN_QUOTES, context, acceptor);
  }

  private void proposeAndAccept(CompoundElement proposalText, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    proposeAndAccept(proposalText.toString(), context, acceptor);
  }

  private boolean isBoolProposalValid(ContentAssistContext context) {
    MessageField field = fieldFrom(context);
    return field != null && messageFields.isBool(field);
  }

  private boolean isNanProposalValid(ContentAssistContext context) {
    MessageField field = fieldFrom(context);
    return field != null && messageFields.isFloatingPointNumber(field);
  }

  private MessageField fieldFrom(ContentAssistContext context) {
    EObject model = context.getCurrentModel();
    if (model instanceof MessageField) {
      return (MessageField) model;
    }
    if (model instanceof AbstractOption) {
      AbstractOption option = (AbstractOption) model;
      IndexedElement source = options.rootSourceOf(option);
      if (source instanceof MessageField) {
        return (MessageField) source;
      }
    }
    return null;
  }

  private boolean proposeOpeningBracket(ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
    EObject model = context.getCurrentModel();
    if (model instanceof ComplexValue) {
      return true;
    }
    if (model instanceof MessageField) {
      MessageField field = (MessageField) model;
      ModifierEnum modifier = field.getModifier();
      if (OPTIONAL.equals(modifier)) {
        CompoundElement display = DEFAULT_EQUAL_IN_BRACKETS;
        int cursorPosition = display.indexOf(CLOSING_BRACKET);
        if (messageFields.isString(field)) {
          display = DEFAULT_EQUAL_STRING_IN_BRACKETS;
          cursorPosition++;
        }
        createAndAccept(display, cursorPosition, context, acceptor);
      }
      return true;
    }
    return false;
  }

  private <T> T extractElementFromContext(ContentAssistContext context, Class<T> type) {
    EObject model = context.getCurrentModel();
    // this is most likely a bug in Xtext:
    if (!type.isInstance(model)) {
      model = context.getPreviousModel();
    }
    if (!type.isInstance(model)) {
      return null;
    }
    return type.cast(model);
  }

  private ICompletionProposal createCompletionProposal(CompoundElement proposal, ContentAssistContext context) {
    return createCompletionProposal(proposal.toString(), context);
  }

  @Override public void completeLiteral_Index(EObject model, Assignment assignment, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    long index = literals.calculateNewIndexOf((Literal) model);
    proposeIndex(index, context, acceptor);
  }

  @Override public void completeLiteralLink_Target(EObject model, Assignment assignment, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    MessageField field = null;
    if (model instanceof DefaultValueFieldOption) {
      field = (MessageField) model.eContainer();
    }
    if (field == null || !messageFields.isOptional(field)) {
      return;
    }
    Enum enumType = messageFields.enumTypeOf(field);
    if (enumType != null) {
      proposeAndAccept(enumType, context, acceptor);
    }
  }

  @Override public void completeMessageField_Index(EObject model, Assignment assignment, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    long index = indexedElements.calculateNewIndexFor((MessageField) model);
    proposeIndex(index, context, acceptor);
  }

  private void proposeIndex(long index, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
    proposeAndAccept(valueOf(index), context, acceptor);
  }

  @Override public void completeMessageField_Name(EObject model, Assignment assignment, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    String typeName = toFirstLower(messageFields.typeNameOf((MessageField) model));
    int index = 1;
    String name = typeName + index;
    for (EObject o : model.eContainer().eContents()) {
      if (o == model || !(o instanceof MessageField)) {
        continue;
      }
      MessageField field = (MessageField) o;
      if (!name.equals(field.getName())) {
        continue;
      }
      name = typeName + (++index);
    }
    proposeAndAccept(name, context, acceptor);
  }

  private void proposeAndAccept(String proposalText, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    acceptor.accept(createCompletionProposal(proposalText, context));
  }

  @Override protected ICompletionProposal createCompletionProposal(String proposalText, ContentAssistContext context) {
    return createCompletionProposal(proposalText, null, defaultImage(), getPriorityHelper().getDefaultPriority(),
        context.getPrefix(), context);
  }

  private Image defaultImage() {
    return imageHelper.getImage(images.defaultImage());
  }

  @Override public void completeNativeFieldOption_Source(EObject model, Assignment assignment,
      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
    MessageField field = extractElementFromContext(context, MessageField.class);
    if (field != null) {
      proposeNativeOptions(field, context, acceptor);
    }
  }

  private void proposeNativeOptions(MessageField field, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    List<String> optionNames = existingFieldOptionNames(field);
    proposeDefaultKeyword(field, optionNames, context, acceptor);
    ProtoDescriptor descriptor =
        descriptorProvider.primaryDescriptor(EResources.getProjectOf(context.getResource()));
    for (MessageField optionSource : descriptor.availableOptionsFor(field)) {
      String optionName = optionSource.getName();
      if (optionNames.contains(optionName) || ("packed".equals(optionName) && !canBePacked(field))) {
        continue;
      }
      proposeOption(optionSource, context, acceptor);
    }
  }

  private List<String> existingFieldOptionNames(IndexedElement e) {
    List<FieldOption> allFieldOptions = indexedElements.fieldOptionsOf(e);
    if (allFieldOptions.isEmpty()) {
      return emptyList();
    }
    List<String> optionNames = newArrayList();
    for (FieldOption option : allFieldOptions) {
      optionNames.add(options.nameOf(option));
    }
    return optionNames;
  }

  private void proposeDefaultKeyword(IndexedElement e, List<String> existingOptionNames, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    if (e instanceof MessageField) {
      MessageField field = (MessageField) e;
      if (!messageFields.isOptional(field) || existingOptionNames.contains(DEFAULT.toString())) {
        return;
      }
      CompoundElement display = DEFAULT_EQUAL;
      int cursorPosition = display.charCount();
      if (messageFields.isString(field)) {
        display = DEFAULT_EQUAL_STRING;
        cursorPosition++;
      }
      createAndAccept(display, cursorPosition, context, acceptor);
    }
  }

  private boolean canBePacked(IndexedElement e) {
    if (e instanceof MessageField) {
      MessageField field = (MessageField) e;
      return messageFields.isPrimitive(field) && REPEATED.equals(field.getModifier());
    }
    return false;
  }

  private void proposeOption(MessageField optionSource, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    String displayString = optionSource.getName();
    String proposalText = displayString + space() + EQUAL + space();
    Object value = defaultValueOf(optionSource);
    if (value != null) {
      proposalText = proposalText + value;
    }
    ICompletionProposal proposal = createCompletionProposal(proposalText, displayString, imageForOption(), context);
    if (value == EMPTY_STRING && proposal instanceof ConfigurableCompletionProposal) {
      // set cursor between the proposal's quotes
      ConfigurableCompletionProposal configurable = (ConfigurableCompletionProposal) proposal;
      configurable.setCursorPosition(proposalText.length() - 1);
    }
    acceptor.accept(proposal);
  }

  private Object defaultValueOf(MessageField field) {
    if (messageFields.isBool(field)) {
      return TRUE;
    }
    if (messageFields.isString(field)) {
      return EMPTY_STRING;
    }
    return null;
  }

  @Override public void completeDefaultValueFieldOption_Value(EObject model, Assignment assignment,
      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
    MessageField field = null;
    if (model instanceof DefaultValueFieldOption) {
      field = (MessageField) model.eContainer();
    }
    if (model instanceof MessageField) {
      field = (MessageField) model;
    }
    if (field == null || !messageFields.isOptional(field)) {
      return;
    }
    proposeFieldValue(field, context, acceptor);
  }

  @Override public void completeNativeFieldOption_Value(EObject model, Assignment assignment,
      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
    if (model instanceof NativeFieldOption) {
      NativeFieldOption option = (NativeFieldOption) model;
      ProtoDescriptor descriptor =
          descriptorProvider.primaryDescriptor(EResources.getProjectOf(context.getResource()));
      MessageField field = (MessageField) options.rootSourceOf(option);
      Enum enumType = descriptor.enumTypeOf(field);
      if (enumType != null) {
        proposeAndAccept(enumType, context, acceptor);
        return;
      }
      proposePrimitiveValues(field, context, acceptor);
    }
  }

  private boolean proposePrimitiveValues(MessageField field, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    if (messageFields.isBool(field)) {
      proposeBooleanValues(context, acceptor);
      return true;
    }
    if (messageFields.isString(field)) {
      proposeEmptyString(context, acceptor);
      return true;
    }
    return false;
  }

  private void proposeBooleanValues(ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
    CommonKeyword[] keywords = { FALSE, TRUE };
    proposeAndAccept(keywords, context, acceptor);
  }

  private void proposeAndAccept(CommonKeyword[] keywords, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    for (CommonKeyword keyword : keywords) {
      proposeAndAccept(keyword.toString(), context, acceptor);
    }
  }

  private void proposeEmptyString(ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
    createAndAccept(EMPTY_STRING, 1, context, acceptor);
  }

  private void createAndAccept(CompoundElement display, int cursorPosition, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    ICompletionProposal proposal = createCompletionProposal(display, context);
    if (proposal instanceof ConfigurableCompletionProposal) {
      ConfigurableCompletionProposal configurable = (ConfigurableCompletionProposal) proposal;
      configurable.setCursorPosition(cursorPosition);
    }
    acceptor.accept(proposal);
  }

  @Override public void completeCustomOption_Source(EObject model, Assignment assignment,
      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
    completeAbstractCustomOptionSource(model, context, acceptor);
  }

  @Override public void completeCustomFieldOption_Source(EObject model, Assignment assignment,
      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
    completeAbstractCustomOptionSource(model, context, acceptor);
  }

  private void completeAbstractCustomOptionSource(EObject model, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    if (model instanceof AbstractCustomOption) {
      AbstractCustomOption option = (AbstractCustomOption) model;
      Collection<IEObjectDescription> scope = scopeProvider().potentialSourcesFor(option);
      proposeAndAcceptOptions(scope, context, acceptor);
    }
  }

  private void proposeAndAcceptOptions(Collection<IEObjectDescription> scope, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    Image image = imageForOption();
    for (IEObjectDescription d : descriptionChooser.shortestQualifiedNamesIn(scope)) {
      proposeAndAccept(d, image, context, acceptor);
    }
  }

  private Image imageForOption() {
    return imageHelper.getImage(images.imageFor(OPTION));
  }

  private void proposeAndAccept(IEObjectDescription d, Image image, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    proposeAndAccept(d, null, null, image, context, acceptor);
  }

  @Override public void completeCustomOption_Fields(EObject model, Assignment assignment,
      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
    if (model instanceof CustomOption) {
      CustomOption option = (CustomOption) model;
      proposeAndAccept(scopeProvider().potentialMessageFieldsFor(option), context, acceptor);
      proposeAndAccept(scopeProvider().potentialExtensionFieldsFor(option), "(%s)", "(%s)", context, acceptor);
    }
  }

  @Override public void completeCustomFieldOption_Fields(EObject model, Assignment assignment,
      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
    if (model instanceof CustomFieldOption) {
      CustomFieldOption option = (CustomFieldOption) model;
      proposeAndAccept(scopeProvider().potentialMessageFieldsFor(option), context, acceptor);
      proposeExtensionFields(scopeProvider().potentialExtensionFieldsFor(option), context, acceptor);
    }
  }

  private void proposeExtensionFields(Collection<IEObjectDescription> scope, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    String format = "(%s)";
    proposeAndAccept(scope, format, format, context, acceptor);
  }

  private void proposeAndAccept(Collection<IEObjectDescription> scope, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    proposeAndAccept(scope, null, null, context, acceptor);
  }

  @Override public void completeOptionSource_Target(EObject model, Assignment assignment,
      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
  }

  @Override public void completeMessageOptionField_Target(EObject model, Assignment assignment,
      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
  }

  @Override public void completeExtensionOptionField_Target(EObject model, Assignment assignment,
      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
  }

  @Override public void complete_MessageOptionField(EObject model, RuleCall ruleCall,
      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {}

  @Override public void complete_ExtensionOptionField(EObject model, RuleCall ruleCall,
      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {}

  @Override public void completeCustomOption_Value(EObject model, Assignment assignment, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    if (model instanceof CustomOption) {
      CustomOption option = (CustomOption) model;
      IndexedElement e = options.sourceOfLastFieldIn(option);
      if (e == null) {
        e = options.rootSourceOf(option);
      }
      if (e instanceof MessageField) {
        proposeFieldValue((MessageField) e, context, acceptor);
      }
    }
  }

  @Override public void completeCustomFieldOption_Value(EObject model, Assignment assignment,
      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
    // TODO content assist returns "{"
    if (model instanceof CustomFieldOption) {
      // TODO check if this is the same as sourceOf
      CustomFieldOption option = (CustomFieldOption) model;
      IndexedElement e = options.sourceOfLastFieldIn(option);
      if (e == null) {
        e = options.rootSourceOf(option);
      }
      if (e instanceof MessageField) {
        proposeFieldValue((MessageField) e, context, acceptor);
      }
    }
  }

  private void proposeFieldValue(MessageField field, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    if (field == null || proposePrimitiveValues(field, context, acceptor)) {
      return;
    }
    Enum enumType = messageFields.enumTypeOf(field);
    if (enumType != null) {
      proposeAndAccept(enumType, context, acceptor);
    }
  }

  private void proposeAndAccept(Enum enumType, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
    Image image = imageHelper.getImage(images.imageFor(LITERAL));
    for (Literal literal : getAllContentsOfType(enumType, Literal.class)) {
      proposeAndAccept(literal.getName(), image, context, acceptor);
    }
  }

  @Override public void completeNormalFieldName_Target(EObject model, Assignment assignment,
      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
  }

  @Override public void completeExtensionFieldName_Target(EObject model, Assignment assignment,
      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
  }

  @Override public void completeSimpleValueField_Value(EObject model, Assignment assignment,
      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
    if (model instanceof SimpleValueField) {
      SimpleValueField field = (SimpleValueField) model;
      FieldName name = field.getName();
      if (name != null) {
        IndexedElement target = name.getTarget();
        if (target instanceof MessageField) {
          proposeFieldValue((MessageField) target, context, acceptor);
        }
      }
    }
  }

  @Override public void completeSimpleValueField_Name(EObject model, Assignment assignment,
      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
    if (model instanceof ComplexValue) {
      ComplexValue value = (ComplexValue) model;
      proposeAndAccept(scopeProvider().potentialNormalFieldNames(value), "%s:", null, context, acceptor);
      proposeAndAccept(scopeProvider().potentialExtensionFieldNames(value), "[%s]:", "[%s]", context, acceptor);
    }
  }

  private void proposeAndAccept(Collection<IEObjectDescription> scope, String proposalFormat, String displayFormat,
      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
    for (IEObjectDescription d : descriptionChooser.shortestQualifiedNamesIn(scope)) {
      Image image = imageHelper.getImage(images.imageFor(d.getEObjectOrProxy()));
      proposeAndAccept(d, proposalFormat, displayFormat, image, context, acceptor);
    }
  }

  private void proposeAndAccept(IEObjectDescription d, String proposalFormat, String displayFormat, Image image,
      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
    QualifiedName name = d.getName();
    String proposalText = name.toString();
    if (!isEmpty(proposalFormat)) {
      proposalText = String.format(proposalFormat, proposalText);
    }
    String lastSegment = name.getLastSegment();
    if (!isEmpty(displayFormat)) {
      lastSegment = String.format(displayFormat, lastSegment);
    }
    String display = String.format("%s - %s", lastSegment, name.toString());
    ICompletionProposal proposal = createCompletionProposal(proposalText, display, image, context);
    acceptor.accept(proposal);
  }

  private void proposeAndAccept(String proposalText, Image image, ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    ICompletionProposal proposal = createCompletionProposal(proposalText, proposalText, image, context);
    acceptor.accept(proposal);
  }

  private ScopeProvider scopeProvider() {
    return (ProtobufScopeProvider) super.getScopeProvider();
  }

  @Override public ICompletionProposal createCompletionProposal(String proposal, String displayString, Image image,
      ContentAssistContext contentAssistContext) {
    StyledString styled = null;
    if (displayString != null) {
      styled = new StyledString(displayString);
    }
    int priority = getPriorityHelper().getDefaultPriority();
    String prefix = contentAssistContext.getPrefix();
    return createCompletionProposal(proposal, styled, image, priority, prefix, contentAssistContext);
  }
}
