| /* |
| * 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.model.util; |
| |
| import static java.util.Collections.unmodifiableList; |
| |
| import static org.eclipse.xtext.util.Strings.isEmpty; |
| |
| import java.util.List; |
| |
| import com.google.eclipse.protobuf.naming.NameResolver; |
| import com.google.eclipse.protobuf.protobuf.AbstractCustomOption; |
| import com.google.eclipse.protobuf.protobuf.AbstractOption; |
| import com.google.eclipse.protobuf.protobuf.DefaultValueFieldOption; |
| import com.google.eclipse.protobuf.protobuf.FieldOption; |
| import com.google.eclipse.protobuf.protobuf.Group; |
| import com.google.eclipse.protobuf.protobuf.IndexedElement; |
| import com.google.eclipse.protobuf.protobuf.MessageField; |
| 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.OptionField; |
| import com.google.eclipse.protobuf.protobuf.OptionSource; |
| import com.google.inject.Inject; |
| import com.google.inject.Singleton; |
| |
| /** |
| * Utility methods related to <code>{@link Option}</code>s. |
| * |
| * @author alruiz@google.com (Alex Ruiz) |
| */ |
| @Singleton public class Options { |
| @Inject private ModelObjects modelObjects; |
| @Inject private NameResolver nameResolver; |
| @Inject private OptionFields optionFields; |
| |
| public boolean isNative(AbstractOption option) { |
| return option instanceof NativeOption || option instanceof NativeFieldOption; |
| } |
| |
| @SuppressWarnings("unchecked") |
| public List<OptionField> fieldsOf(AbstractCustomOption option) { |
| List<OptionField> fields = modelObjects.valueOfFeature(option, "fields", List.class); |
| return unmodifiableList(fields); |
| } |
| |
| /** |
| * Indicates whether the given option is the "default value" one. |
| * @param option the given option to check. |
| * @return {@code true} if the given option is the "default value" one, {@code false} otherwise. |
| */ |
| public boolean isDefaultValueOption(FieldOption option) { |
| return option instanceof DefaultValueFieldOption && option.eContainer() instanceof MessageField; |
| } |
| |
| /** |
| * Returns the <code>{@link IndexedElement}</code> the given custom option is referring to. This method will check |
| * first the source of the last field of the given option (if any.) If the option does not have any fields, this |
| * method will return the root source of the option. |
| * <p> |
| * Example #1 |
| * |
| * <pre> |
| * option(myOption) = true; |
| * </pre> |
| * |
| * this method will return the <code>{@link IndexedElement}</code> "myOption" is pointing to. |
| * </p> |
| * <p> |
| * Example #2 |
| * |
| * <pre> |
| * option(myOption).foo = true; |
| * </pre> |
| * |
| * this method will return the <code>{@link IndexedElement}</code> "foo" is pointing to. |
| * </p> |
| * @param option the given custom option. |
| * @return the {@code IndexedElement} the given custom option is referring to, or {@code null} if it cannot be |
| * found. |
| */ |
| public IndexedElement sourceOf(AbstractCustomOption option) { |
| IndexedElement e = sourceOfLastFieldIn(option); |
| if (e == null) { |
| e = rootSourceOf((AbstractOption) option); |
| } |
| return e; |
| } |
| |
| /** |
| * Returns the last field of the given custom option. In the following example |
| * |
| * <pre> |
| * option(myOption).foo = true; |
| * </pre> |
| * |
| * this method will return the field that "foo" is pointing to. |
| * @param option the given custom option. |
| * @return the last field of the given custom option is referring to, or {@code null} if one cannot be found. |
| */ |
| @SuppressWarnings("unchecked") |
| public IndexedElement sourceOfLastFieldIn(AbstractCustomOption option) { |
| List<OptionField> fields = modelObjects.valueOfFeature(option, "fields", List.class); |
| if (fields == null || fields.isEmpty()) { |
| return null; |
| } |
| OptionField last = fields.get(fields.size() - 1); |
| return optionFields.sourceOf(last); |
| } |
| |
| /** |
| * Returns the <code>{@link IndexedElement}</code> the given option is referring to. In the following example |
| * |
| * <pre> |
| * option(myOption).foo = true; |
| * </pre> |
| * |
| * this method will return the <code>{@link IndexedElement}</code> "myOption" is pointing to. |
| * @param option the given option. |
| * @return the {@code Property} the given option is referring to, or {@code null} if it cannot be found. |
| */ |
| public IndexedElement rootSourceOf(AbstractOption option) { |
| OptionSource source = modelObjects.valueOfFeature(option, "source", OptionSource.class); |
| return source == null ? null : source.getTarget(); |
| } |
| |
| /** |
| * Returns the name of the given <code>{@link IndexedElement}</code> that is being used as a source of an option. If |
| * the given element is a <code>{@link Group}</code>, this method will return its name in lower case. |
| * @param optionSource the given {@code IndexedElement} that is being used as a source of an option. |
| * @return the name of the given {@code IndexedElement}. |
| */ |
| public String nameForOption(IndexedElement optionSource) { |
| String name = nameResolver.nameOf(optionSource); |
| if (optionSource instanceof Group && !isEmpty(name)) { |
| name = name.toLowerCase(); |
| } |
| return name; |
| } |
| |
| /** |
| * Returns the name of the given option. |
| * @param option the given option. |
| * @return the name of the given option. |
| */ |
| public String nameOf(FieldOption option) { |
| IndexedElement e = rootSourceOf(option); |
| if (e instanceof MessageField) { |
| return ((MessageField) e).getName(); |
| } |
| return null; |
| } |
| } |