Merge "Update installation instructions to include information about compiling the code."
diff --git a/com.google.eclipse.protobuf.feature/feature.xml b/com.google.eclipse.protobuf.feature/feature.xml
index 7e273e5..d12a6be 100644
--- a/com.google.eclipse.protobuf.feature/feature.xml
+++ b/com.google.eclipse.protobuf.feature/feature.xml
@@ -50,4 +50,11 @@
          version="0.0.0"
          unpack="false"/>
 
+   <plugin
+         id="com.google.eclipse.protobuf.generator"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
 </feature>
diff --git a/com.google.eclipse.protobuf.generator/.classpath b/com.google.eclipse.protobuf.generator/.classpath
new file mode 100644
index 0000000..eca7bdb
--- /dev/null
+++ b/com.google.eclipse.protobuf.generator/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/com.google.eclipse.protobuf.generator/.gitignore b/com.google.eclipse.protobuf.generator/.gitignore
new file mode 100644
index 0000000..ae3c172
--- /dev/null
+++ b/com.google.eclipse.protobuf.generator/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/com.google.eclipse.protobuf.generator/.project b/com.google.eclipse.protobuf.generator/.project
new file mode 100644
index 0000000..de89a7e
--- /dev/null
+++ b/com.google.eclipse.protobuf.generator/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>com.google.eclipse.protobuf.generator</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
+	</natures>
+</projectDescription>
diff --git a/com.google.eclipse.protobuf.generator/.settings/org.eclipse.jdt.core.prefs b/com.google.eclipse.protobuf.generator/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..0c68a61
--- /dev/null
+++ b/com.google.eclipse.protobuf.generator/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/com.google.eclipse.protobuf.generator/META-INF/MANIFEST.MF b/com.google.eclipse.protobuf.generator/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..173239d
--- /dev/null
+++ b/com.google.eclipse.protobuf.generator/META-INF/MANIFEST.MF
@@ -0,0 +1,23 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Protobuf Editor Generator
+Bundle-SymbolicName: com.google.eclipse.protobuf.generator
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: com.google.eclipse.protobuf.generator.Activator
+Bundle-Vendor: Google
+Require-Bundle: org.antlr.runtime,
+ org.apache.commons.logging,
+ org.apache.log4j,
+ org.eclipse.core.resources,
+ org.eclipse.core.runtime,
+ org.eclipse.emf.common,
+ org.eclipse.emf.ecore,
+ org.eclipse.emf.mwe2.launch;resolution:=optional,
+ org.eclipse.jdt.annotation;resolution:=optional,
+ org.eclipse.xtext,
+ org.eclipse.xtext.generator;resolution:=optional,
+ org.eclipse.xtext.ui,
+ org.eclipse.xtext.util
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Bundle-ActivationPolicy: lazy
+Export-Package: com.google.eclipse.protobuf
diff --git a/com.google.eclipse.protobuf.generator/build.properties b/com.google.eclipse.protobuf.generator/build.properties
new file mode 100644
index 0000000..34d2e4d
--- /dev/null
+++ b/com.google.eclipse.protobuf.generator/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/GenerateProtobuf.mwe2 b/com.google.eclipse.protobuf.generator/src/com/google/eclipse/protobuf/GenerateProtobuf.mwe2
similarity index 100%
rename from com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/GenerateProtobuf.mwe2
rename to com.google.eclipse.protobuf.generator/src/com/google/eclipse/protobuf/GenerateProtobuf.mwe2
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/Protobuf.xtext b/com.google.eclipse.protobuf.generator/src/com/google/eclipse/protobuf/Protobuf.xtext
similarity index 100%
rename from com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/Protobuf.xtext
rename to com.google.eclipse.protobuf.generator/src/com/google/eclipse/protobuf/Protobuf.xtext
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/ProtobufEcorePostProcessor.java b/com.google.eclipse.protobuf.generator/src/com/google/eclipse/protobuf/ProtobufEcorePostProcessor.java
similarity index 100%
rename from com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/ProtobufEcorePostProcessor.java
rename to com.google.eclipse.protobuf.generator/src/com/google/eclipse/protobuf/ProtobufEcorePostProcessor.java
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/ProtobufGenerator.java b/com.google.eclipse.protobuf.generator/src/com/google/eclipse/protobuf/ProtobufGenerator.java
similarity index 100%
rename from com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/ProtobufGenerator.java
rename to com.google.eclipse.protobuf.generator/src/com/google/eclipse/protobuf/ProtobufGenerator.java
diff --git a/com.google.eclipse.protobuf.generator/src/com/google/eclipse/protobuf/conversion/DOUBLEValueConverter.java b/com.google.eclipse.protobuf.generator/src/com/google/eclipse/protobuf/conversion/DOUBLEValueConverter.java
new file mode 100644
index 0000000..2052e0a
--- /dev/null
+++ b/com.google.eclipse.protobuf.generator/src/com/google/eclipse/protobuf/conversion/DOUBLEValueConverter.java
@@ -0,0 +1,65 @@
+/*
+ * 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.conversion;
+
+import static java.lang.Double.NEGATIVE_INFINITY;
+import static java.lang.Double.NaN;
+import static java.lang.Double.POSITIVE_INFINITY;
+
+import static org.eclipse.xtext.util.Strings.isEmpty;
+
+import static com.google.common.collect.Maps.newHashMap;
+
+import java.util.Map;
+
+import org.eclipse.xtext.conversion.ValueConverterException;
+import org.eclipse.xtext.conversion.impl.AbstractLexerBasedConverter;
+import org.eclipse.xtext.nodemodel.INode;
+
+/**
+ * Converts floating-point numbers to {@code double}s.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class DOUBLEValueConverter extends AbstractLexerBasedConverter<Double> {
+  private static final Map<String, Double> PREDEFINED_VALUES = newHashMap();
+
+  static {
+    PREDEFINED_VALUES.put("nan", NaN);
+    PREDEFINED_VALUES.put("inf", POSITIVE_INFINITY);
+    PREDEFINED_VALUES.put("-inf", NEGATIVE_INFINITY);
+  }
+
+  /**
+   * Creates an {@code float} from the given input, if the given input represents a floating-point number.
+   * @param string the given input.
+   * @param node the parsed node including hidden parts.
+   * @return the new {@code float}.
+   * @throws ValueConverterException if the given input is {@code null}, empty or does not represent a floating-point
+   * number.
+   */
+  @Override public Double toValue(String string, INode node) throws ValueConverterException {
+    if (isEmpty(string)) {
+      throw new ValueConverterException("Couldn't convert empty string to double.", node, null);
+    }
+    Double predefinedValue = PREDEFINED_VALUES.get(string);
+    if (predefinedValue != null) {
+      return predefinedValue;
+    }
+    try {
+      return Double.parseDouble(string);
+    } catch (NumberFormatException e) {
+      throw parsingError(string, node, e);
+    }
+  }
+
+  private ValueConverterException parsingError(String string, INode node, Exception cause) {
+    return new ValueConverterException("Couldn't convert '" + string + "' to double.", node, cause);
+  }
+}
diff --git a/com.google.eclipse.protobuf.generator/src/com/google/eclipse/protobuf/conversion/HEXValueConverter.java b/com.google.eclipse.protobuf.generator/src/com/google/eclipse/protobuf/conversion/HEXValueConverter.java
new file mode 100644
index 0000000..adb6208
--- /dev/null
+++ b/com.google.eclipse.protobuf.generator/src/com/google/eclipse/protobuf/conversion/HEXValueConverter.java
@@ -0,0 +1,76 @@
+/*
+ * 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.conversion;
+
+import static org.eclipse.xtext.util.Strings.isEmpty;
+
+import java.math.BigInteger;
+
+import org.eclipse.xtext.conversion.ValueConverterException;
+import org.eclipse.xtext.conversion.impl.AbstractLexerBasedConverter;
+import org.eclipse.xtext.nodemodel.INode;
+
+/**
+ * Converts hexadecimal numbers to {@code long}s.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class HEXValueConverter extends AbstractLexerBasedConverter<Long> {
+  private static final String[] VALID_PREFIXES = { "0x", "-0x", "0X", "-0X" };
+
+  /**
+   * Creates an {@code int} from the given input, if the given input represents an hexadecimal number.
+   * @param string the given input.
+   * @param node the parsed node including hidden parts.
+   * @return the new {@code int}.
+   * @throws ValueConverterException if the given input is {@code null}, empty or does not represent an hexadecimal
+   * number.
+   */
+  @Override public Long toValue(String string, INode node) throws ValueConverterException {
+    if (isEmpty(string)) {
+      throw new ValueConverterException("Couldn't convert empty string to long.", node, null);
+    }
+    if (!startsWithValidPrefix(string)) {
+      throw parsingError(string, node);
+    }
+    String withoutZeroX = removeZeroX(string);
+    try {
+      BigInteger value = new BigInteger(withoutZeroX, 16);
+      long longValue = value.longValue();
+      return longValue != -1 ? longValue : 1L;
+    } catch (NumberFormatException e) {
+      throw parsingError(string, node, e);
+    }
+  }
+
+  private boolean startsWithValidPrefix(String string) {
+    for (String prefix : VALID_PREFIXES) {
+      if (string.startsWith(prefix)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private String removeZeroX(String string) {
+    if (string.startsWith("-")) {
+      String withoutSign = string.substring(3, string.length());
+      return "-" + withoutSign;
+    }
+    return string.substring(2, string.length());
+  }
+
+  private ValueConverterException parsingError(String string, INode node) {
+    return parsingError(string, node, null);
+  }
+
+  private ValueConverterException parsingError(String string, INode node, Exception cause) {
+    return new ValueConverterException("Couldn't convert '" + string + "' to long.", node, cause);
+  }
+}
diff --git a/com.google.eclipse.protobuf.generator/src/com/google/eclipse/protobuf/conversion/LONGValueConverter.java b/com.google.eclipse.protobuf.generator/src/com/google/eclipse/protobuf/conversion/LONGValueConverter.java
new file mode 100644
index 0000000..491761f
--- /dev/null
+++ b/com.google.eclipse.protobuf.generator/src/com/google/eclipse/protobuf/conversion/LONGValueConverter.java
@@ -0,0 +1,57 @@
+/*
+ * 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.conversion;
+
+import static org.eclipse.xtext.util.Strings.isEmpty;
+
+import java.math.BigInteger;
+
+import org.eclipse.xtext.conversion.ValueConverterException;
+import org.eclipse.xtext.conversion.impl.AbstractLexerBasedConverter;
+import org.eclipse.xtext.nodemodel.INode;
+
+/**
+ * Converts numbers to {@code long}s.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class LONGValueConverter extends AbstractLexerBasedConverter<Long> {
+  /**
+   * Creates an {@code int} from the given input, if the given input represents an integer number.
+   * @param string the given input.
+   * @param node the parsed node including hidden parts.
+   * @return the new {@code int}.
+   * @throws ValueConverterException if the given input is {@code null}, empty or does not represent an integer number.
+   */
+  @Override public Long toValue(String string, INode node) throws ValueConverterException {
+    if (isEmpty(string)) {
+      throw new ValueConverterException("Couldn't convert empty string to long.", node, null);
+    }
+    try {
+      return Long.parseLong(string, 10);
+    } catch (NumberFormatException e) {
+      return parseUsingBigInteger(string, node);
+    }
+  }
+
+  private Long parseUsingBigInteger(String string, INode node) {
+    // error could be overflow, parse again with BigInteger.
+    try {
+      BigInteger value = new BigInteger(string, 10);
+      long longValue = value.longValue();
+      return longValue != -1 ? longValue : 1L;
+    } catch (NumberFormatException e) {
+      throw parsingError(string, node, e);
+    }
+  }
+
+  private ValueConverterException parsingError(String string, INode node, Exception cause) {
+    return new ValueConverterException("Couldn't convert '" + string + "' to long.", node, cause);
+  }
+}
diff --git a/com.google.eclipse.protobuf.generator/src/com/google/eclipse/protobuf/conversion/ProtobufTerminalConverters.java b/com.google.eclipse.protobuf.generator/src/com/google/eclipse/protobuf/conversion/ProtobufTerminalConverters.java
new file mode 100644
index 0000000..8a57a6a
--- /dev/null
+++ b/com.google.eclipse.protobuf.generator/src/com/google/eclipse/protobuf/conversion/ProtobufTerminalConverters.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2014 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.conversion;
+
+import com.google.inject.Inject;
+
+import org.eclipse.xtext.common.services.DefaultTerminalConverters;
+import org.eclipse.xtext.conversion.IValueConverter;
+import org.eclipse.xtext.conversion.ValueConverter;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class ProtobufTerminalConverters extends DefaultTerminalConverters {
+  @Inject private DOUBLEValueConverter doubleValueConverter;
+  @Inject private HEXValueConverter hexValueConverter;
+  @Inject private LONGValueConverter longValueConverter;
+
+  @ValueConverter(rule = "DOUBLE")
+  public IValueConverter<Double> DOUBLE() {
+    return doubleValueConverter;
+  }
+
+  @ValueConverter(rule = "HEX")
+  public IValueConverter<Long> HEX() {
+    return hexValueConverter;
+  }
+
+  @ValueConverter(rule = "LONG")
+  public IValueConverter<Long> LONG() {
+    return longValueConverter;
+  }
+}
diff --git a/com.google.eclipse.protobuf.generator/src/com/google/eclipse/protobuf/generator/Activator.java b/com.google.eclipse.protobuf.generator/src/com/google/eclipse/protobuf/generator/Activator.java
new file mode 100644
index 0000000..9bd59b3
--- /dev/null
+++ b/com.google.eclipse.protobuf.generator/src/com/google/eclipse/protobuf/generator/Activator.java
@@ -0,0 +1,30 @@
+package com.google.eclipse.protobuf.generator;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class Activator implements BundleActivator {
+
+	private static BundleContext context;
+
+	static BundleContext getContext() {
+		return context;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext bundleContext) throws Exception {
+		Activator.context = bundleContext;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext bundleContext) throws Exception {
+		Activator.context = null;
+	}
+
+}
diff --git a/com.google.eclipse.protobuf/META-INF/MANIFEST.MF b/com.google.eclipse.protobuf/META-INF/MANIFEST.MF
index e76431d..589dac1 100644
--- a/com.google.eclipse.protobuf/META-INF/MANIFEST.MF
+++ b/com.google.eclipse.protobuf/META-INF/MANIFEST.MF
@@ -18,7 +18,8 @@
  org.eclipse.xtext,

  org.eclipse.xtext.generator;resolution:=optional,

  org.eclipse.xtext.ui,

- org.eclipse.xtext.util

+ org.eclipse.xtext.util,

+ com.google.eclipse.protobuf.generator;bundle-version="1.0.0"

 Bundle-RequiredExecutionEnvironment: JavaSE-1.8

 Export-Package: com.google.eclipse.protobuf,

  com.google.eclipse.protobuf.conversion,