ru.makkarpov.scalingua.CompiledLanguage.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scalingua-core_2.13 Show documentation
Show all versions of scalingua-core_2.13 Show documentation
A minimal set of runtime classes for Scalingua
The newest version!
/******************************************************************************
* Copyright © 2016 Maxim Karpov *
* *
* 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. *
******************************************************************************/
package ru.makkarpov.scalingua
import java.io.{DataInputStream, IOException, InputStream}
import ru.makkarpov.scalingua.MergedLanguage.MessageData
object CompiledLanguage {
class EnglishTags extends TaggedLanguage {
private var singularTag: Map[String, String] = _
private var pluralTag: Map[String, (String, String)] = _
protected def initialize(is: InputStream): Unit = {
if (is == null)
throw new NullPointerException("inputStream")
val singTag = Map.newBuilder[String, String]
val plurTag = Map.newBuilder[String, (String, String)]
val dis = new DataInputStream(is)
var flag = true
try {
dis.readUTF()
while (flag)
dis.readByte() match {
case 0 => flag = false
case 5 =>
val id = dis.readUTF()
val msg = dis.readUTF()
singTag += id -> msg
case 6 =>
val id = dis.readUTF()
val msgSing = dis.readUTF()
val msgPlur = dis.readUTF()
plurTag += id -> (msgSing, msgPlur)
}
} finally dis.close()
singularTag = singTag.result()
pluralTag = plurTag.result()
}
/** @inheritdoc */
override def taggedSingular(tag: String): String = singularTag.getOrElse(tag, tag)
/** @inheritdoc */
override def taggedPlural(tag: String, n: Long): String =
pluralTag.get(tag) match {
case Some((sing, plur)) => if (n != 1) plur else sing
case None => tag
}
}
}
/**
* A compiled representation of .po file that requires much less code to parse. We cannot embed all strings
* in Scala file since Java has limit on constant pool (65k) and on length of single string (also 65k).
* So we extract them to separate file and keep in Scala class only compiled plural function.
*
* This class is just a stub, actual implementation will be generated by SBT plugin.
*/
abstract class CompiledLanguage extends Language with PluralFunction with TaggedLanguage {
// We cannot pass input stream as constructor parameter here, since we need to read resource
// from same ClassLoader that loaded `Language_xx_XX` instance, but we cannot use `getClass` in
// constructor parameter. So we delay the initializaiton of Maps until getClass will be available
private var _id: LanguageId = _
private var singular: Map[String, String] = _
private var singularCtx: Map[(String, String), String] = _
private var plural: Map[String, Seq[String]] = _
private var pluralCtx: Map[(String, String), Seq[String]] = _
private var singularTag: Map[String, String] = _
private var pluralTag: Map[String, Seq[String]] = _
protected def initialize(is: InputStream): Unit = {
if (is == null)
throw new NullPointerException("inputStream")
val sing = Map.newBuilder[String, String]
val plur = Map.newBuilder[String, Seq[String]]
val singCtx = Map.newBuilder[(String, String), String]
val plurCtx = Map.newBuilder[(String, String), Seq[String]]
val singTag = Map.newBuilder[String, String]
val plurTag = Map.newBuilder[String, Seq[String]]
val dis = new DataInputStream(is)
var flag = true
try {
dis.readUTF() // Source hash for caching purposes
_id = LanguageId(dis.readUTF(), dis.readUTF())
def readPlurals: Seq[String] =
(0 until dis.readUnsignedByte()) map (_ => dis.readUTF())
while (flag) dis.readByte() match {
case 0 => flag = false
case 1 =>
val id = dis.readUTF()
sing += id -> dis.readUTF()
case 2 =>
val ctx = dis.readUTF()
val id = dis.readUTF()
singCtx += (ctx, id) -> dis.readUTF()
case 3 =>
val id = dis.readUTF()
plur += id -> readPlurals
case 4 =>
val ctx = dis.readUTF()
val id = dis.readUTF()
plurCtx += (ctx, id) -> readPlurals
case 5 =>
val tag = dis.readUTF()
val msg = dis.readUTF()
singTag += tag -> msg
case 6 =>
val tag = dis.readUTF()
val msg = readPlurals
plurTag += tag -> msg
}
} finally dis.close()
singular = sing.result()
plural = plur.result()
singularCtx = singCtx.result()
pluralCtx = plurCtx.result()
singularTag = singTag.result()
pluralTag = plurTag.result()
}
override def id: LanguageId = _id
def messageData = MessageData(singular, singularCtx, plural, pluralCtx)
override def singular(msgid: String): String = singular.getOrElse(msgid, msgid)
override def singular(msgctx: String, msgid: String): String = singularCtx.getOrElse(msgctx -> msgid, msgid)
override def plural(msgid: String, msgidPlural: String, n: Long): String = plural.get(msgid) match {
case Some(tr) => tr(plural(n))
case None => if (n == 1) msgid else msgidPlural
}
override def plural(msgctx: String, msgid: String, msgidPlural: String, n: Long): String =
pluralCtx.get(msgctx -> msgid) match {
case Some(tr) => tr(plural(n))
case None => if (n == 1) msgid else msgidPlural
}
override def taggedSingular(tag: String): String =
if (singularTag.contains(tag)) singularTag(tag) else taggedFallback.taggedSingular(tag)
override def taggedPlural(tag: String, n: Long): String =
if (pluralTag.contains(tag)) pluralTag(tag)(plural(n)) else taggedFallback.taggedPlural(tag, n)
override def merge(other: Language): Language = other match {
case ml: MergedLanguage => new MergedLanguage(id, messageData.merge(ml.data), this, this)
case cc: CompiledLanguage => new MergedLanguage(id, messageData.merge(cc.messageData), this, this)
case _: Language.English => other
case _ => throw new NotImplementedError("Merge is supported only for MergedLanguage and CompiledLanguage")
}
def taggedFallback: TaggedLanguage
}